1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Add error type and message to CHECK() macro.

A CHECK() worked exactly like ASSERT() except that it was compiled into production code. However, over time many checks have been added that should not throw AssertError, which should be reserved for probable coding errors.

Allow the error code to be specified so other error types can be thrown. Also add a human-readable message since many of these could be seen by users even when there is no coding error.

Update coverage exceptions for CHECK() to match ASSERT() since all conditions will never be covered.
This commit is contained in:
David Steele 2021-11-30 16:21:15 -05:00
parent 0895cfcdf7
commit 9c76056dd0
40 changed files with 119 additions and 113 deletions

View File

@ -54,15 +54,15 @@ yamlNew(const Buffer *const buffer)
*this = (Yaml){{0}}; // Extra braces are required for older gcc versions
// Initialize parser context
CHECK(yaml_parser_initialize(&this->parser));
CHECK(ServiceError, yaml_parser_initialize(&this->parser), "unable to initialize yaml parser");
memContextCallbackSet(objMemContext(this), yamlFreeResource, this);
// Set yaml string
yaml_parser_set_input_string(&this->parser, bufPtrConst(buffer), bufUsed(buffer));
// Start document
CHECK(yamlEventNext(this).type == yamlEventTypeStreamBegin);
CHECK(yamlEventNext(this).type == yamlEventTypeDocBegin);
CHECK(FormatError, yamlEventNext(this).type == yamlEventTypeStreamBegin, "expected yaml stream begin");
CHECK(FormatError, yamlEventNext(this).type == yamlEventTypeDocBegin, "expected yaml document begin");
}
OBJ_NEW_END();
@ -111,7 +111,7 @@ yamlEventType(yaml_event_type_t type)
FUNCTION_TEST_RETURN(yamlEventTypeMapEnd);
default:
CHECK(type == YAML_NO_EVENT);
CHECK(FormatError, type == YAML_NO_EVENT, "expected yaml no event");
FUNCTION_TEST_RETURN(yamlEventTypeNone);
}
}
@ -130,7 +130,7 @@ yamlEventNext(Yaml *this)
if (!yaml_parser_parse(&this->parser, &event))
{
// These should always be set
CHECK(this->parser.problem_mark.line && this->parser.problem_mark.column);
CHECK(ServiceError, this->parser.problem_mark.line && this->parser.problem_mark.column, "invalid yaml error info");
THROW_FMT(
FormatError, "yaml parse error: %s at line: %lu column: %lu", this->parser.problem,

View File

@ -13,7 +13,7 @@ int
main(int argListSize, const char *argList[])
{
// Check parameters
CHECK(argListSize <= 2);
CHECK(ParamInvalidError, argListSize <= 2, "only one parameter allowed");
// Initialize logging
logInit(logLevelWarn, logLevelError, logLevelOff, false, 0, 1, false);

View File

@ -346,11 +346,11 @@ bldCfgParseAllowList(Yaml *const yaml, const List *const optList)
{
// Else allow list is inherited
CHECK(optList != NULL);
CHECK(AssertError, optList != NULL, "option list is NULL");
yamlEventCheck(allowListVal, yamlEventTypeScalar);
const BldCfgOptionRaw *const optInherit = lstFind(optList, &allowListVal.value);
CHECK(optInherit != NULL);
CHECK(AssertError, optInherit != NULL, "inherited option is NULL");
MEM_CONTEXT_PRIOR_BEGIN()
{
@ -359,7 +359,7 @@ bldCfgParseAllowList(Yaml *const yaml, const List *const optList)
MEM_CONTEXT_PRIOR_END();
}
CHECK(result != NULL);
CHECK(AssertError, result != NULL, "result is NULL");
}
MEM_CONTEXT_TEMP_END();
@ -461,7 +461,7 @@ bldCfgParseDepend(Yaml *const yaml, const List *const optList)
else
{
// Else depend is inherited
CHECK(optList != NULL);
CHECK(AssertError, optList != NULL, "option list is NULL");
yamlEventCheck(dependVal, yamlEventTypeScalar);
const BldCfgOptionRaw *const optInherit = lstFind(optList, &dependVal.value);
@ -543,7 +543,7 @@ bldCfgParseOptionDeprecate(Yaml *const yaml)
MEM_CONTEXT_PRIOR_END();
deprecate = lstFind(result, &name);
CHECK(deprecate != NULL);
CHECK(AssertError, deprecate != NULL, "deprecate is NULL");
}
// Set indexed/unindexed flags
@ -700,11 +700,11 @@ bldCfgParseOptionCommandList(Yaml *const yaml, const List *const optList)
// Else command list is inherited
else
{
CHECK(optList != NULL);
CHECK(AssertError, optList != NULL, "option list is NULL");
yamlEventCheck(optCmdVal, yamlEventTypeScalar);
const BldCfgOptionRaw *const optInherit = lstFind(optList, &optCmdVal.value);
CHECK(optInherit != NULL);
CHECK(AssertError, optInherit != NULL, "inherited option is NULL");
result = optInherit->cmdList;
}
@ -797,7 +797,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
else if (strEqZ(optDef.value, "inherit"))
{
const BldCfgOptionRaw *const optInherit = lstFind(optListRaw, &optDefVal.value);
CHECK(optInherit != NULL);
CHECK(AssertError, optInherit != NULL, "inherited option is NULL");
optRaw = *optInherit;
optRaw.name = opt.value;
@ -971,7 +971,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
optCmd.roleList = cmd->roleList;
}
CHECK(optCmd.roleList != NULL);
CHECK(AssertError, optCmd.roleList != NULL, "role list is NULL");
MEM_CONTEXT_BEGIN(lstMemContext(cmdOptList))
{
@ -992,7 +992,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
}
const BldCfgOption *const opt = lstGet(result, optRawIdx);
CHECK(strEq(opt->name, optRaw->name));
CHECK(AssertError, strEq(opt->name, optRaw->name), "option name does not equal raw option name");
// Assigning to const pointers this way is definitely cheating, but since we allocated the memory and know exactly where
// it is so this is the easiest way to avoid a lot of indirection due to the dependency of BldCfgOptionDepend on

View File

@ -392,7 +392,7 @@ bldCfgRenderScalar(const String *const scalar, const String *const optType)
}
else
{
CHECK(strEq(optType, OPT_TYPE_SIZE_STR) || strEq(optType, OPT_TYPE_INTEGER_STR));
CHECK(AssertError, strEq(optType, OPT_TYPE_SIZE_STR) || strEq(optType, OPT_TYPE_INTEGER_STR), "invalid type");
value = cvtZToInt64(strZ(scalar));
}

View File

@ -13,7 +13,7 @@ int
main(int argListSize, const char *argList[])
{
// Check parameters
CHECK(argListSize <= 2);
CHECK(ParamInvalidError, argListSize <= 2, "only one parameter allowed");
// Initialize logging
logInit(logLevelWarn, logLevelError, logLevelOff, false, 0, 1, false);

View File

@ -14,7 +14,7 @@ int
main(int argListSize, const char *argList[])
{
// Check parameters
CHECK(argListSize <= 2);
CHECK(ParamInvalidError, argListSize <= 2, "only one parameter allowed");
// Initialize logging
logInit(logLevelWarn, logLevelError, logLevelOff, false, 0, 1, false);

View File

@ -154,7 +154,7 @@ bldHlpValidate(const BldHlp bldHlp, const BldCfg bldCfg)
{
const BldCfgOptionCommand *const optCmd = lstGet(opt->cmdList, optCmdListIdx);
const BldHlpCommand *const cmdHlp = lstFind(bldHlp.cmdList, &optCmd->name);
CHECK(cmdHlp != NULL);
CHECK(AssertError, cmdHlp != NULL, "command help is NULL");
// Only options with a command role of main require help
if (!strLstExists(optCmd->roleList, CMD_ROLE_MAIN_STR))

View File

@ -133,7 +133,7 @@ bldHlpRenderHelpAutoCPack(const BldCfg bldCfg, const BldHlp bldHlp)
{
const BldCfgCommand *const cmd = lstGet(bldCfg.cmdList, cmdIdx);
const BldHlpCommand *const cmdHlp = lstFind(bldHlp.cmdList, &cmd->name);
CHECK(cmdHlp != NULL);
CHECK(AssertError, cmdHlp != NULL, "command help is NULL");
pckWriteBoolP(pack, cmd->internal);
pckWriteStrP(pack, bldHlpRenderXml(cmdHlp->summary));
@ -209,7 +209,7 @@ bldHlpRenderHelpAutoCPack(const BldCfg bldCfg, const BldHlp bldHlp)
if (optCmd != NULL)
{
const BldHlpCommand *const cmdHlp = lstFind(bldHlp.cmdList, &cmd->name);
CHECK(cmdHlp != NULL);
CHECK(AssertError, cmdHlp != NULL, "command help is NULL");
const BldHlpOption *const cmdOptHlp = cmdHlp->optList != NULL ? lstFind(cmdHlp->optList, &opt->name) : NULL;
if (opt->internal != optCmd->internal || cmdOptHlp != NULL)

View File

@ -274,7 +274,7 @@ archiveAsyncExec(ArchiveMode archiveMode, const StringList *commandExec)
THROW_ON_SYS_ERROR(waitpid(pid, &processStatus, 0) == -1, ExecuteError, "unable to wait for forked process");
// The first fork should exit with success. If not, something went wrong during the second fork.
CHECK(WIFEXITED(processStatus) && WEXITSTATUS(processStatus) == 0);
CHECK(ExecuteError, WIFEXITED(processStatus) && WEXITSTATUS(processStatus) == 0, "error on first fork");
#ifdef DEBUG_EXEC_TIME
// If the process does not exit immediately then something probably went wrong with the double fork. It's possible that this

View File

@ -393,9 +393,11 @@ backupBuildIncrPrior(const InfoBackup *infoBackup)
// There's a small chance that the prior manifest is old enough that backupOptionCompressLevel was not recorded.
// There's an even smaller chance that the user will also alter compression-type in this scenario right after
// upgrading to a newer version. Because we judge this combination of events to be nearly impossible just assert
// upgrading to a newer version. Because we judge this combination of events to be nearly impossible just check
// here so no test coverage is needed.
CHECK(manifestPriorData->backupOptionCompressLevel != NULL);
CHECK(
FormatError, manifestPriorData->backupOptionCompressLevel != NULL,
"compress-level missing in prior manifest");
// Set the compression level back to whatever was in the prior backup
cfgOptionSet(
@ -1130,7 +1132,7 @@ backupJobResultPageChecksum(PackRead *const checksumPageResult)
}
// Check that the array was not empty
CHECK(first);
CHECK(FormatError, first, "page checksum result array is empty");
// Output last page or page range
backupJobResultPageChecksumOut(result, pageBegin, pageEnd);
@ -1256,8 +1258,8 @@ backupJobResult(
else
{
// Format the page checksum errors
CHECK(checksumPageErrorList != NULL);
CHECK(!varLstEmpty(checksumPageErrorList));
CHECK(FormatError, checksumPageErrorList != NULL, "page checksum error list is missing");
CHECK(FormatError, !varLstEmpty(checksumPageErrorList), "page checksum error list is empty");
String *error = strNew();
unsigned int errorTotalMin = 0;
@ -1453,8 +1455,7 @@ backupProcessQueue(Manifest *manifest, List **queueList)
do
{
// A target should always be found
CHECK(targetIdx < strLstSize(targetList));
CHECK(AssertError, targetIdx < strLstSize(targetList), "backup target not found");
if (strBeginsWith(file->name, strLstGet(targetList, targetIdx)))
break;

View File

@ -390,7 +390,9 @@ helpRender(const Buffer *const helpData)
if (strLstEmpty(cfgCommandParam()))
{
// Output command summary and description. Add a warning for internal commands.
CHECK(commandData[commandId].summary != NULL && commandData[commandId].description != NULL);
CHECK(
AssertError, commandData[commandId].summary != NULL && commandData[commandId].description != NULL,
"command help missing");
strCatFmt(
result,
@ -502,7 +504,9 @@ helpRender(const Buffer *const helpData)
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", strZ(optionName), commandName);
// Output option summary and description. Add a warning for internal options.
CHECK(optionData[option.id].summary != NULL && optionData[option.id].description != NULL);
CHECK(
AssertError, optionData[option.id].summary != NULL && optionData[option.id].description != NULL,
"option help missing");
strCatFmt(
result,

View File

@ -41,7 +41,7 @@ cmdRemote(ProtocolServer *const server)
TRY_BEGIN()
{
// Get the command. No need to check parameters since we know this is the first noop.
CHECK(protocolServerCommandGet(server).id == PROTOCOL_COMMAND_NOOP);
CHECK(FormatError, protocolServerCommandGet(server).id == PROTOCOL_COMMAND_NOOP, "noop expected");
// Only try the lock if this is process 0, i.e. the remote started from the main process
if (cfgOptionUInt(cfgOptProcess) == 0)

View File

@ -394,7 +394,7 @@ restoreManifestValidate(Manifest *manifest, const String *backupSet)
MEM_CONTEXT_TEMP_BEGIN()
{
// If there are no files in the manifest then something has gone horribly wrong
CHECK(manifestFileTotal(manifest) > 0);
CHECK(FormatError, manifestFileTotal(manifest) > 0, "manifest missing files");
// Sanity check to ensure the manifest has not been moved to a new directory
const ManifestData *data = manifestData(manifest);
@ -554,7 +554,7 @@ restoreManifestMap(Manifest *manifest)
const ManifestPath *const path = manifestPathFindDefault(manifest, manifestName, NULL);
const ManifestFile *const file = manifestFileFindDefault(manifest, manifestName, NULL);
CHECK(path == NULL || file == NULL);
CHECK(FormatError, path == NULL || file == NULL, "link may not be both file and path");
target = (ManifestTarget){.name = manifestName, .path = linkPath, .type = manifestTargetTypeLink};
@ -590,7 +590,7 @@ restoreManifestMap(Manifest *manifest)
target.path = linkPath;
// The target must be a link since pg_data/ was prepended and pgdata is the only allowed path
CHECK(target.type == manifestTargetTypeLink);
CHECK(FormatError, target.type == manifestTargetTypeLink, "target must be a link");
// Error if the target is a tablespace
if (target.tablespaceId != 0)
@ -1986,7 +1986,7 @@ restoreProcessQueue(Manifest *manifest, List **queueList)
do
{
// A target should always be found
CHECK(targetIdx < strLstSize(targetList));
CHECK(FormatError, targetIdx < strLstSize(targetList), "backup target not found");
if (strBeginsWith(file->name, strLstGet(targetList, targetIdx)))
break;

View File

@ -67,7 +67,7 @@ cmdServer(uint64_t connectionMax)
THROW_ON_SYS_ERROR(waitpid(pid, &processStatus, 0) == -1, ExecuteError, "unable to wait for forked process");
// The first fork should exit with success. If not, something went wrong during the second fork.
CHECK(WIFEXITED(processStatus) && WEXITSTATUS(processStatus) == 0);
CHECK(ExecuteError, WIFEXITED(processStatus) && WEXITSTATUS(processStatus) == 0, "error on first fork");
}
// Free the socket since the child is now using it

View File

@ -44,11 +44,11 @@ Asserts are used in test code to ensure that certain conditions are true. They
/***********************************************************************************************************************************
Checks are used in production builds to test very important conditions. Be sure to limit use to the most critical cases.
***********************************************************************************************************************************/
#define CHECK(condition) \
#define CHECK(type, condition, message) \
do \
{ \
if (!(condition)) \
THROW_FMT(AssertError, "check '%s' failed", #condition); \
THROW(type, message); \
} \
while (0)

View File

@ -67,8 +67,8 @@ ioFilterProcessIn(IoFilter *this, const Buffer *input)
ASSERT(this != NULL);
ASSERT(this->pub.interface.in != NULL);
CHECK(input == NULL || !bufEmpty(input));
CHECK(!this->flushing || input == NULL);
CHECK(AssertError, input == NULL || !bufEmpty(input), "expected data or flush");
CHECK(AssertError, !this->flushing || input == NULL, "no data allowed after flush");
if (input == NULL)
this->flushing = true;
@ -91,8 +91,8 @@ ioFilterProcessInOut(IoFilter *this, const Buffer *input, Buffer *output)
ASSERT(this != NULL);
ASSERT(output != NULL);
ASSERT(this->pub.interface.inOut != NULL);
CHECK(input == NULL || !bufEmpty(input));
CHECK(!this->flushing || input == NULL);
CHECK(AssertError, input == NULL || !bufEmpty(input), "expected data or flush");
CHECK(AssertError, !this->flushing || input == NULL, "no data allowed after flush");
if (input == NULL && !this->flushing)
this->flushing = true;
@ -100,7 +100,8 @@ ioFilterProcessInOut(IoFilter *this, const Buffer *input, Buffer *output)
if (!ioFilterDone(this))
this->pub.interface.inOut(this->pub.driver, input, output);
CHECK(!ioFilterInputSame(this) || !bufEmpty(output));
CHECK(AssertError, !ioFilterInputSame(this) || !bufEmpty(output), "expected input same or output");
FUNCTION_TEST_RETURN_VOID();
}

View File

@ -60,10 +60,10 @@ tlsCertCommonName(X509 *const certificate)
FUNCTION_TEST_END(); // {vm_covered}
X509_NAME *const subjectName = X509_get_subject_name(certificate); // {vm_covered}
CHECK(subjectName != NULL); // {vm_covered}
CHECK(FormatError, subjectName != NULL, "subject name is missing"); // {vm_covered}
const int commonNameIndex = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); // {vm_covered}
CHECK(commonNameIndex >= 0); // {vm_covered}
CHECK(FormatError, commonNameIndex >= 0, "common name is missing"); // {vm_covered}
String *result = tlsAsn1ToStr(X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjectName, commonNameIndex))); // {vm_covered}
@ -78,7 +78,7 @@ tlsCertCommonName(X509 *const certificate)
static int
tlsCertPwd(char *buffer, const int size, const int rwFlag, void *const userData)
{
CHECK(size > 0);
CHECK(ServiceError, size > 0, "buffer has zero size");
(void)rwFlag; (void)userData;
// No password is currently supplied

View File

@ -267,8 +267,7 @@ tlsSessionWrite(THIS_VOID, const Buffer *buffer)
result = tlsSessionResult(this, SSL_write(this->session, bufPtrConst(buffer), (int)bufUsed(buffer)), false);
// Either a retry or all data was written
CHECK(result == 0 || (size_t)result == bufUsed(buffer));
CHECK(ServiceError, result == 0 || (size_t)result == bufUsed(buffer), "expected retry or complete write");
}
FUNCTION_LOG_RETURN_VOID();

View File

@ -122,7 +122,7 @@ logLevelEnum(const StringId logLevelId)
break;
// Check that the log level was found
CHECK(result != LOG_LEVEL_TOTAL);
CHECK(AssertError, result != LOG_LEVEL_TOTAL, "invalid log level");
FUNCTION_TEST_RETURN(result);
}

View File

@ -553,7 +553,9 @@ pckReadTagNext(PackRead *this)
if (this->tagNextTypeMap == 0xF)
this->tagNextTypeMap = (unsigned int)pckReadU64Internal(this) + 0xF;
CHECK(this->tagNextTypeMap < PACK_TYPE_MAP_SIZE && packTypeMapData[this->tagNextTypeMap].type != 0);
CHECK(
FormatError, this->tagNextTypeMap < PACK_TYPE_MAP_SIZE && packTypeMapData[this->tagNextTypeMap].type != 0,
"invalid tag type");
// If the value can contain multiple bits (e.g. integer)
if (packTypeMapData[this->tagNextTypeMap].valueMultiBit)
@ -1267,7 +1269,7 @@ pckReadEnd(PackRead *this)
FUNCTION_TEST_END();
ASSERT(this != NULL);
CHECK(this->tagStack.depth == 0);
CHECK(FormatError, this->tagStack.depth == 0, "invalid pack end read in container");
// Make sure we are at the end of the pack
unsigned int id = UINT_MAX - 1;
@ -1463,7 +1465,7 @@ pckWriteTag(PackWrite *this, PackTypeMap typeMap, unsigned int id, uint64_t valu
}
// Else the id must be greater than the last one
else
CHECK(id > this->tagStack.top->idLast);
CHECK(AssertError, id > this->tagStack.top->idLast, "field id must be greater than last id");
// Clear NULLs now that field id has been calculated
this->tagStack.top->nullTotal = 0;

View File

@ -323,7 +323,7 @@ strResize(String *this, size_t requested)
if (requested > this->pub.extra)
{
// Fixed size strings may not be resized
CHECK(!STR_IS_FIXED_BUFFER());
CHECK(AssertError, !STR_IS_FIXED_BUFFER(), "resize of fixed size string");
// Check size
CHECK_SIZE(strSize(this) + requested);

View File

@ -303,7 +303,7 @@ strIdToZN(StringId strId, char *const buffer)
// 6-bit decoding
default:
{
CHECK(bit == stringIdBit6);
ASSERT(bit == stringIdBit6);
// Map to convert encoding to characters
const char map[64] = "!abcdefghijklmnopqrstuvwxyz-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

View File

@ -31,7 +31,7 @@ configOptionProtocol(PackRead *const param, ProtocolServer *const server)
while (pckReadNext(param))
{
CfgParseOptionResult option = cfgParseOptionP(pckReadStrP(param));
CHECK(option.found);
CHECK(AssertError, option.found, "option not found");
varLstAdd(optionList, varDup(cfgOptionIdxVar(option.id, cfgOptionKeyToIdx(option.id, option.keyIdx + 1))));
}

View File

@ -137,7 +137,7 @@ dbExec(Db *this, const String *command)
ASSERT(this != NULL);
ASSERT(command != NULL);
CHECK(dbQuery(this, command) == NULL);
CHECK(AssertError, dbQuery(this, command) == NULL, "exec returned data");
FUNCTION_LOG_RETURN_VOID();
}
@ -158,8 +158,8 @@ dbQueryColumn(Db *this, const String *query)
VariantList *result = dbQuery(this, query);
CHECK(varLstSize(result) == 1);
CHECK(varLstSize(varVarLst(varLstGet(result, 0))) == 1);
CHECK(AssertError, varLstSize(result) == 1, "query must return one column");
CHECK(AssertError, varLstSize(varVarLst(varLstGet(result, 0))) == 1, "query must return one row");
FUNCTION_LOG_RETURN(VARIANT, varLstGet(varVarLst(varLstGet(result, 0)), 0));
}
@ -180,7 +180,7 @@ dbQueryRow(Db *this, const String *query)
VariantList *result = dbQuery(this, query);
CHECK(varLstSize(result) == 1);
CHECK(AssertError, varLstSize(result) == 1, "query must return one row");
FUNCTION_LOG_RETURN(VARIANT_LIST, varVarLst(varLstGet(result, 0)));
}
@ -332,8 +332,7 @@ dbBackupStart(Db *const this, const bool startFast, const bool stopAuto, const b
// If stop-auto is enabled check for a running backup
if (stopAuto)
{
// Feature is not supported in PostgreSQL < 9.3
CHECK(dbPgVersion(this) >= PG_VERSION_93);
CHECK(AssertError, dbPgVersion(this) >= PG_VERSION_93, "feature not supported in PostgreSQL < " PG_VERSION_93_STR);
// Feature is not needed for PostgreSQL >= 9.6 since backups are run in non-exclusive mode
if (dbPgVersion(this) < PG_VERSION_96)

View File

@ -497,8 +497,7 @@ infoLoad(const String *error, InfoLoadCallback *callbackFunction, void *callback
loaded = callbackFunction(callbackData, try);
done = true;
// There must be at least one attempt to load the file
CHECK(loaded || try > 0);
CHECK(AssertError, loaded || try > 0, "file load must be attempted");
}
CATCH_ANY()
{

View File

@ -185,11 +185,8 @@ infoPgNewLoad(IoRead *read, InfoPgType type, InfoLoadNewCallback *callbackFuncti
this->pub.info = infoNewLoad(read, infoPgLoadCallback, &loadData);
// History must include at least one item or the file is corrupt
CHECK(!lstEmpty(this->pub.history));
// If the current id was not found then the file is corrupt
CHECK(loadData.currentId > 0);
CHECK(FormatError, !lstEmpty(this->pub.history), "history is missing");
CHECK(FormatError, loadData.currentId > 0, "current id is missing");
// Find the current history item
for (unsigned int historyIdx = 0; historyIdx < lstSize(this->pub.history); historyIdx++)
@ -198,8 +195,7 @@ infoPgNewLoad(IoRead *read, InfoPgType type, InfoLoadNewCallback *callbackFuncti
this->historyCurrent = historyIdx;
}
// If the current id did not match the history list then the file is corrupt
CHECK(this->historyCurrent != UINT_MAX);
CHECK(FormatError, this->historyCurrent != UINT_MAX, "unable to find current id in history");
}
OBJ_NEW_END();

View File

@ -998,8 +998,7 @@ manifestBuildCallback(void *data, const StorageInfo *info)
// Else it must be a file or special (since we have already checked if it is a link)
else
{
// Tablespace links should never be to a file
CHECK(target.tablespaceId == 0);
CHECK(FormatError, target.tablespaceId == 0, "tablespace links to a file");
// Identify target as a file
target.path = strPath(info->linkDestination);
@ -1548,7 +1547,7 @@ manifestOwnerGet(const Variant *owner)
// If bool then it should be false. This indicates that the owner could not be mapped to a name during the backup.
if (varType(owner) == varTypeBool)
{
CHECK(!varBool(owner));
CHECK(FormatError, !varBool(owner), "owner bool must be false");
FUNCTION_TEST_RETURN(NULL);
}
@ -1569,7 +1568,7 @@ manifestOwnerDefaultGet(const Variant *ownerDefault)
if (varType(ownerDefault) == varTypeBool)
{
// Value must be false
CHECK(!varBool(ownerDefault));
CHECK(FormatError, !varBool(ownerDefault), "owner bool must be false");
FUNCTION_TEST_RETURN(BOOL_FALSE_VAR);
}

View File

@ -127,7 +127,7 @@ pgClientOpen(PgClient *this)
FUNCTION_LOG_END();
ASSERT(this != NULL);
CHECK(this->connection == NULL);
CHECK(AssertError, this->connection == NULL, "invalid connection");
MEM_CONTEXT_TEMP_BEGIN()
{
@ -175,7 +175,7 @@ pgClientQuery(PgClient *this, const String *query)
FUNCTION_LOG_END();
ASSERT(this != NULL);
CHECK(this->connection != NULL);
CHECK(AssertError, this->connection != NULL, "invalid connection");
ASSERT(query != NULL);
VariantList *result = NULL;
@ -319,8 +319,7 @@ pgClientQuery(PgClient *this, const String *query)
// Free the result
PQclear(pgResult);
// Need to get a NULL result to complete the request
CHECK(PQgetResult(this->connection) == NULL);
CHECK(ServiceError, PQgetResult(this->connection) == NULL, "NULL result required to complete request");
}
TRY_END();

View File

@ -490,7 +490,7 @@ pgLsnFromStr(const String *lsn)
{
StringList *lsnPart = strLstNewSplit(lsn, FSLASH_STR);
CHECK(strLstSize(lsnPart) == 2);
CHECK(FormatError, strLstSize(lsnPart) == 2, "lsn requires two parts");
result = (cvtZToUInt64Base(strZ(strLstGet(lsnPart, 0)), 16) << 32) + cvtZToUInt64Base(strZ(strLstGet(lsnPart, 1)), 16);
}

View File

@ -243,7 +243,7 @@ protocolClientError(ProtocolClient *const this, const ProtocolMessageType type,
// Switch state to idle after error (server will do the same)
this->state = protocolClientStateIdle;
CHECK(message != NULL && stack != NULL);
CHECK(FormatError, message != NULL && stack != NULL, "invalid error data");
errorInternalThrow(type, __FILE__, __func__, __LINE__, strZ(message), strZ(stack));
}
@ -276,7 +276,7 @@ protocolClientDataGet(ProtocolClient *const this)
protocolClientError(this, type, response);
CHECK(type == protocolMessageTypeData);
CHECK(FormatError, type == protocolMessageTypeData, "expected data message");
MEM_CONTEXT_PRIOR_BEGIN()
{
@ -315,7 +315,7 @@ protocolClientDataEndGet(ProtocolClient *const this)
protocolClientError(this, type, response);
CHECK(type == protocolMessageTypeDataEnd);
CHECK(FormatError, type == protocolMessageTypeDataEnd, "expected data end message");
pckReadEndP(response);

View File

@ -382,7 +382,8 @@ protocolServer(IoServer *const tlsServer, IoSession *const socketSession)
TRY_BEGIN()
{
// Get list of authorized stanzas for this client
CHECK(cfgOptionTest(cfgOptTlsServerAuth));
CHECK(AssertError, cfgOptionTest(cfgOptTlsServerAuth), "missing auth data");
const String *const clientAuthList = strDup(
varStr(kvGet(cfgOptionKv(cfgOptTlsServerAuth), VARSTR(ioSessionPeerName(tlsSession)))));
@ -392,7 +393,7 @@ protocolServer(IoServer *const tlsServer, IoSession *const socketSession)
// Get parameter list from the client and load it
const ProtocolServerCommandGetResult command = protocolServerCommandGet(result);
CHECK(command.id == PROTOCOL_COMMAND_CONFIG);
CHECK(FormatError, command.id == PROTOCOL_COMMAND_CONFIG, "expected config command");
StringList *const paramList = pckReadStrLstP(pckReadNew(command.param));
strLstInsert(paramList, 0, cfgExe());
@ -753,7 +754,7 @@ protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostIdx)
if (cfgOptionTest(cfgOptProcess))
processId = cfgOptionUInt(cfgOptProcess);
CHECK(hostIdx < protocolHelper.clientRemoteSize);
CHECK(AssertError, hostIdx < protocolHelper.clientRemoteSize, "invalid host");
// Create protocol object
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientRemote[hostIdx];

View File

@ -119,7 +119,7 @@ protocolServerCommandGet(ProtocolServer *const this)
PackRead *const command = pckReadNewIo(this->read);
ProtocolMessageType type = (ProtocolMessageType)pckReadU32P(command);
CHECK(type == protocolMessageTypeCommand);
CHECK(FormatError, type == protocolMessageTypeCommand, "expected command message");
MEM_CONTEXT_PRIOR_BEGIN()
{
@ -314,7 +314,7 @@ protocolServerDataGet(ProtocolServer *const this)
PackRead *data = pckReadNewIo(this->read);
ProtocolMessageType type = (ProtocolMessageType)pckReadU32P(data);
CHECK(type == protocolMessageTypeData);
CHECK(FormatError, type == protocolMessageTypeData, "expected data message");
MEM_CONTEXT_PRIOR_BEGIN()
{

View File

@ -138,13 +138,13 @@ storageGcsAuthToken(HttpRequest *request, time_t timeBegin)
{
// Get token
result.tokenType = strDup(varStr(kvGet(kvResponse, GCS_JSON_TOKEN_TYPE_VAR)));
CHECK(result.tokenType != NULL);
CHECK(FormatError, result.tokenType != NULL, "token type missing");
result.token = strDup(varStr(kvGet(kvResponse, GCS_JSON_ACCESS_TOKEN_VAR)));
CHECK(result.token != NULL);
CHECK(FormatError, result.token != NULL, "access token missing");
// Get expiration
const Variant *const expiresIn = kvGet(kvResponse, GCS_JSON_EXPIRES_IN_VAR);
CHECK(expiresIn != NULL);
CHECK(FormatError, expiresIn != NULL, "expiry missing");
result.timeExpire = timeBegin + (time_t)varInt64Force(expiresIn);
}
@ -648,7 +648,7 @@ storageGcsListInternal(
for (unsigned int fileIdx = 0; fileIdx < varLstSize(fileList); fileIdx++)
{
const KeyValue *file = varKv(varLstGet(fileList, fileIdx));
CHECK(file != NULL);
CHECK(FormatError, file != NULL, "file missing");
// Get file name
StorageInfo info =
@ -658,7 +658,7 @@ storageGcsListInternal(
.exists = true,
};
CHECK(info.name != NULL);
CHECK(FormatError, info.name != NULL, "file name missing");
// Strip off the base prefix when present
if (!strEmpty(basePrefix))
@ -968,7 +968,7 @@ storageGcsNew(
driver->privateKey = varStr(kvGet(kvKey, GCS_JSON_PRIVATE_KEY_VAR));
const String *const uri = varStr(kvGet(kvKey, GCS_JSON_TOKEN_URI_VAR));
CHECK(driver->credential != NULL && driver->privateKey != NULL && uri != NULL);
CHECK(FormatError, driver->credential != NULL && driver->privateKey != NULL && uri != NULL, "credentials missing");
driver->authUrl = httpUrlNewParseP(uri, .type = httpProtocolTypeHttps);

View File

@ -85,7 +85,7 @@ storageWriteGcsVerify(StorageWriteGcs *this, HttpResponse *response)
// Check the md5 hash
const String *md5base64 = varStr(kvGet(content, GCS_JSON_MD5_HASH_VAR));
CHECK(md5base64 != NULL);
CHECK(FormatError, md5base64 != NULL, "MD5 missing");
const String *md5actual = bufHex(bufNewDecode(encodeBase64, md5base64));
const String *md5expected = pckReadStrP(pckReadNew(ioFilterResult(this->md5hash)));
@ -175,7 +175,7 @@ storageWriteGcsBlockAsync(StorageWriteGcs *this, bool done)
MEM_CONTEXT_BEGIN(THIS_MEM_CONTEXT())
{
this->uploadId = strDup(httpHeaderGet(httpResponseHeader(response), GCS_HEADER_UPLOAD_ID_STR));
CHECK(this->uploadId != NULL);
CHECK(FormatError, this->uploadId != NULL, "upload id missing");
}
MEM_CONTEXT_END();
}

View File

@ -381,7 +381,7 @@ storageRepoGet(unsigned int repoIdx, bool write)
// If no helper was found it try Posix
if (result == NULL)
{
CHECK(type == STORAGE_POSIX_TYPE);
CHECK(AssertError, type == STORAGE_POSIX_TYPE, "invalid storage type");
result = storagePosixNewP(
cfgOptionIdxStr(cfgOptRepoPath, repoIdx), .write = write, .pathExpressionFunction = storageRepoPathExpression);

View File

@ -331,15 +331,15 @@ storageS3AuthAuto(StorageS3 *const this, const HttpHeader *const header)
{
// Check the code field for errors
const Variant *code = kvGetDefault(credential, S3_JSON_TAG_CODE_VAR, VARSTRDEF("code field is missing"));
CHECK(code != NULL);
CHECK(FormatError, code != NULL, "error code missing");
if (!varEq(code, S3_JSON_VALUE_SUCCESS_VAR))
THROW_FMT(FormatError, "unable to retrieve temporary credentials: %s", strZ(varStr(code)));
// Make sure the required values are present
CHECK(kvGet(credential, S3_JSON_TAG_ACCESS_KEY_ID_VAR) != NULL);
CHECK(kvGet(credential, S3_JSON_TAG_SECRET_ACCESS_KEY_VAR) != NULL);
CHECK(kvGet(credential, S3_JSON_TAG_TOKEN_VAR) != NULL);
CHECK(FormatError, kvGet(credential, S3_JSON_TAG_ACCESS_KEY_ID_VAR) != NULL, "access key missing");
CHECK(FormatError, kvGet(credential, S3_JSON_TAG_SECRET_ACCESS_KEY_VAR) != NULL, "secret access key missing");
CHECK(FormatError, kvGet(credential, S3_JSON_TAG_TOKEN_VAR) != NULL, "token missing");
// Copy credentials
this->accessKey = strDup(varStr(kvGet(credential, S3_JSON_TAG_ACCESS_KEY_ID_VAR)));
@ -349,7 +349,7 @@ storageS3AuthAuto(StorageS3 *const this, const HttpHeader *const header)
MEM_CONTEXT_END();
// Update expiration time
CHECK(kvGet(credential, S3_JSON_TAG_EXPIRATION_VAR) != NULL);
CHECK(FormatError, kvGet(credential, S3_JSON_TAG_EXPIRATION_VAR) != NULL, "expiration missing");
this->credExpirationTime = storageS3CvtTime(varStr(kvGet(credential, S3_JSON_TAG_EXPIRATION_VAR)));
FUNCTION_LOG_RETURN_VOID();
@ -383,7 +383,7 @@ storageS3AuthWebId(StorageS3 *const this, const HttpHeader *const header)
this->credHttpClient, HTTP_VERB_GET_STR, FSLASH_STR, .header = header, .query = query);
HttpResponse *const response = httpRequestResponse(request, true);
CHECK(httpResponseCode(response) != HTTP_RESPONSE_CODE_NOT_FOUND);
CHECK(FormatError, httpResponseCode(response) != HTTP_RESPONSE_CODE_NOT_FOUND, "invalid response code");
// Copy credentials
const XmlNode *const xmlCred =
@ -754,11 +754,11 @@ storageS3Info(THIS_VOID, const String *file, StorageInfoLevel level, StorageInte
const HttpHeader *httpHeader = httpResponseHeader(httpResponse);
const String *const contentLength = httpHeaderGet(httpHeader, HTTP_HEADER_CONTENT_LENGTH_STR);
CHECK(contentLength != NULL);
CHECK(FormatError, contentLength != NULL, "content length missing");
result.size = cvtZToUInt64(strZ(contentLength));
const String *const lastModified = httpHeaderGet(httpHeader, HTTP_HEADER_LAST_MODIFIED_STR);
CHECK(lastModified != NULL);
CHECK(FormatError, lastModified != NULL, "last modified missing");
result.timeModified = httpDateToTime(lastModified);
}

View File

@ -75,13 +75,19 @@ storageNew(
};
// If path sync feature is enabled then path feature must be enabled
CHECK(!storageFeature(this, storageFeaturePathSync) || storageFeature(this, storageFeaturePath));
CHECK(
AssertError, !storageFeature(this, storageFeaturePathSync) || storageFeature(this, storageFeaturePath),
"path feature required");
// If hardlink feature is enabled then path feature must be enabled
CHECK(!storageFeature(this, storageFeatureHardLink) || storageFeature(this, storageFeaturePath));
CHECK(
AssertError, !storageFeature(this, storageFeatureHardLink) || storageFeature(this, storageFeaturePath),
"path feature required");
// If symlink feature is enabled then path feature must be enabled
CHECK(!storageFeature(this, storageFeatureSymLink) || storageFeature(this, storageFeaturePath));
CHECK(
AssertError, !storageFeature(this, storageFeatureSymLink) || storageFeature(this, storageFeaturePath),
"path feature required");
FUNCTION_LOG_RETURN(STORAGE, this);
}

View File

@ -39,7 +39,7 @@ sub coverageLCovConfigGenerate
my $bCoverageSummary = shift;
my $strBranchFilter =
'OBJECT_DEFINE_[A-Z0-9_]+\(|\s{4}[A-Z][A-Z0-9_]+\([^\?]*\)|\s{4}(ASSERT|assert|switch\s)\(|\{\+{0,1}' .
'OBJECT_DEFINE_[A-Z0-9_]+\(|\s{4}[A-Z][A-Z0-9_]+\([^\?]*\)|\s{4}(ASSERT|CHECK|assert|switch\s)\(|\{\+{0,1}' .
($bCoverageSummary ? 'uncoverable_branch' : 'uncover(ed|able)_branch');
my $strLineFilter =
'\{\+{0,1}' . ($bCoverageSummary ? 'uncoverable' : '(uncover(ed|able)' . ($bContainer ? '' : '|vm_covered') . ')') . '[^_]';
@ -54,7 +54,7 @@ sub coverageLCovConfigGenerate
"#\n" .
'# OBJECT_DEFINE_[A-Z0-9_]+\( - exclude object definitions' . "\n" .
'# \s{4}[A-Z][A-Z0-9_]+\([^\?]*\) - exclude macros that do not take a conditional parameter and are not themselves a parameter' . "\n" .
'# ASSERT/(|assert\( - exclude asserts since it usually not possible to trigger both branches' . "\n" .
'# ASSERT/(|CHECK/(|assert\( - exclude asserts/checks since it usually not possible to trigger both branches' . "\n" .
'# switch \( - lcov requires default: to show complete coverage but --Wswitch-enum enforces all enum values be present' . "\n" .
"lcov_excl_br_line=${strBranchFilter}\n" .
"\n" .

View File

@ -102,7 +102,7 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("logLevelEnum() and logLevelStr()"))
{
TEST_ERROR(logLevelEnum(strIdFromZ(BOGUS_STR)), AssertError, "check 'result != LOG_LEVEL_TOTAL' failed");
TEST_ERROR(logLevelEnum(strIdFromZ(BOGUS_STR)), AssertError, "invalid log level");
TEST_RESULT_INT(logLevelEnum(strIdFromZ("off")), logLevelOff, "log level 'OFF' found");
TEST_RESULT_INT(logLevelEnum(strIdFromZ("info")), logLevelInfo, "log level 'info' found");
TEST_RESULT_INT(logLevelEnum(strIdFromZ("trace")), logLevelTrace, "log level 'TRACE' found");

View File

@ -1545,7 +1545,7 @@ testRun(void)
static const StorageHelper storageHelperListError[] = {{.type = STORAGE_POSIX_TYPE}, STORAGE_END_HELPER};
storageHelperInit(storageHelperListError);
TEST_ERROR(storageRepoGet(0, true), AssertError, "check 'type == STORAGE_POSIX_TYPE' failed");
TEST_ERROR(storageRepoGet(0, true), AssertError, "invalid storage type");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("storage configuration");