From 44e3ee33d2360127ac715ebb16866cf995863949 Mon Sep 17 00:00:00 2001 From: David Steele Date: Mon, 16 Jun 2025 17:21:33 -0400 Subject: [PATCH] Improve defaults and allow lists with option value dependencies. Some defaults and allow lists were determined in cfgLoadUpdateOption() because they depended on the values of other options, .e.g. compress-level. Instead build this functionality into the config parser. Not only does this standardize the defaults and allow lists but it makes it possible to automate the documentation, which is also done in this commit. --- doc/src/command/build/reference.c | 47 +++- src/build/config/config.yaml | 38 +++- src/build/config/parse.c | 298 ++++++++++++++++++++++---- src/build/config/parse.h | 33 ++- src/build/config/render.c | 171 +++++++++++---- src/build/help/help.xml | 21 +- src/common/compress/bz2/compress.h | 1 - src/common/compress/gz/compress.h | 1 - src/common/compress/helper.c | 58 ----- src/common/compress/helper.intern.h | 21 -- src/common/compress/lz4/compress.h | 1 - src/common/compress/zst/compress.h | 1 - src/config/load.c | 70 +----- src/config/parse.auto.c.inc | 125 ++++++++++- src/config/parse.c | 205 +++++++++++++----- test/code-count/file-type.yaml | 4 - test/src/module/build/configTest.c | 172 +++++++++++++-- test/src/module/command/helpTest.c | 11 +- test/src/module/common/compressTest.c | 28 --- test/src/module/config/loadTest.c | 25 +-- test/src/module/config/parseTest.c | 34 ++- test/src/module/doc/buildTest.c | 72 ++++++- 22 files changed, 1033 insertions(+), 404 deletions(-) delete mode 100644 src/common/compress/helper.intern.h diff --git a/doc/src/command/build/reference.c b/doc/src/command/build/reference.c index ead4e08c4..b5673eae8 100644 --- a/doc/src/command/build/reference.c +++ b/doc/src/command/build/reference.c @@ -44,30 +44,57 @@ referenceOptionRender( xmlNodeChildAdd(xmlOption, optHlp->description); - // Add default value + // Add default value or default map StringList *const blockList = strLstNew(); - const String *const defaultValue = + const BldCfgOptionDefault *const defaultValue = optCmdCfg != NULL && optCmdCfg->defaultValue != NULL ? optCmdCfg->defaultValue : optCfg->defaultValue; if (optCfg->defaultType == defaultTypeDynamic) { - ASSERT(strEqZ(optCfg->defaultValue, "bin")); + ASSERT(strEqZ(defaultValue->value, "bin")); strLstAddZ(blockList, "default: [path of executed pgbackrest binary]"); } else if (defaultValue != NULL) { - if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR)) - strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue, "true") ? "y" : "n"); + if (defaultValue->value != NULL) + { + if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR)) + strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue->value, "true") ? "y" : "n"); + else + strLstAddFmt(blockList, "default: %s", strZ(defaultValue->value)); + } else - strLstAddFmt(blockList, "default: %s", strZ(defaultValue)); + { + strLstAddFmt(blockList, "default (depending on %s):", strZ(optCfg->depend->option->name)); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultValue->mapList); mapIdx++) + { + const BldCfgOptionDefaultMap *const map = lstGet(defaultValue->mapList, mapIdx); + strLstAddFmt(blockList, " %s - %s", strZ(map->map), strZ(map->value)); + } + + strLstAddZ(blockList, ""); + } } // Add allow range - if (optCfg->allowRangeMin != NULL) + if (optCfg->allowRange != NULL) { - ASSERT(optCfg->allowRangeMax != NULL); - strLstAddFmt(blockList, "allowed: %s-%s", strZ(optCfg->allowRangeMin), strZ(optCfg->allowRangeMax)); + if (optCfg->allowRange->mapList != NULL) + { + strLstAddFmt(blockList, "allow range (depending on %s):", strZ(optCfg->depend->option->name)); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(optCfg->allowRange->mapList); mapIdx++) + { + const BldCfgOptionAllowRangeMap *const map = lstGet(optCfg->allowRange->mapList, mapIdx); + strLstAddFmt(blockList, " %s - [%s, %s]", strZ(map->map), strZ(map->min), strZ(map->max)); + } + + strLstAddZ(blockList, ""); + } + else + strLstAddFmt(blockList, "allowed: [%s, %s]", strZ(optCfg->allowRange->min), strZ(optCfg->allowRange->max)); } // Add examples @@ -110,7 +137,7 @@ referenceOptionRender( } if (!strLstEmpty(blockList)) - xmlNodeContentSet(xmlNodeAdd(xmlOption, STRDEF("code-block")), strLstJoin(blockList, "\n")); + xmlNodeContentSet(xmlNodeAdd(xmlOption, STRDEF("code-block")), strTrim(strLstJoin(blockList, "\n"))); // Add deprecated names if (optCfg->deprecateList != NULL) diff --git a/src/build/config/config.yaml b/src/build/config/config.yaml index 7571b4e36..77fc5dba4 100644 --- a/src/build/config/config.yaml +++ b/src/build/config/config.yaml @@ -774,7 +774,25 @@ option: section: global type: integer required: false + default: + - bz2: 9 + - gz: 6 + - lz4: 1 + - zst: 3 + allow-range: + - bz2: [1, 9] + - gz: [-1, 9] + - lz4: [-5, 12] + - zst: [-7, 22] command: compress + depend: + option: compress-type + default: 0 + list: + - bz2 + - gz + - lz4 + - zst command-role: async: {} main: {} @@ -1570,6 +1588,13 @@ option: default: ~ required: false allow-range: [0, 65535] + default: + - tls: 8432 + depend: + option: pg-host-type + list: + - ssh + - tls deprecate: db-ssh-port: {} db?-ssh-port: {} @@ -2228,13 +2253,18 @@ option: type: integer required: false allow-range: [0, 65535] + default: + - tls: 8432 + depend: + option: repo-host-type + list: + - ssh + - tls command: repo-host-cmd command-role: async: {} main: {} local: {} - depend: - option: repo-host deprecate: backup-ssh-port: {} @@ -2621,6 +2651,10 @@ option: group: repo type: size required: false + default: + - azure: 4MiB + - gcs: 4MiB + - s3: 5MiB allow-range: [64KiB, 1TiB] command: repo-type depend: diff --git a/src/build/config/parse.c b/src/build/config/parse.c index dfebab06a..0d95fe25a 100644 --- a/src/build/config/parse.c +++ b/src/build/config/parse.c @@ -267,6 +267,32 @@ bldCfgParseOptionGroupList(Yaml *const yaml) /*********************************************************************************************************************************** Parse option list ***********************************************************************************************************************************/ +typedef struct BldCfgOptionAllowRangeMapRaw // See BldCfgOptionAllowRangeMap for comments +{ + const String *map; + const String *min; + const String *max; +} BldCfgOptionAllowRangeMapRaw; + +typedef struct BldCfgOptionAllowRangeRaw // See BldCfgOptionAllowRange for comments +{ + const String *min; + const String *max; + List *mapList; +} BldCfgOptionAllowRangeRaw; + +typedef struct BldCfgOptionDefaultMapRaw +{ + const String *map; // See BldCfgOptionDefaultMap for comments + const String *value; +} BldCfgOptionDefaultMapRaw; + +typedef struct BldCfgOptionDefaultRaw +{ + const String *value; // See BldCfgOptionDefault for comments + List *mapList; +} BldCfgOptionDefaultRaw; + typedef struct BldCfgOptionDependRaw { const String *option; // See BldCfgOptionDepend for comments @@ -286,7 +312,7 @@ typedef struct BldCfgOptionCommandRaw const String *name; // See BldCfgOptionCommand for comments const Variant *internal; const Variant *required; - const String *defaultValue; + const BldCfgOptionDefaultRaw *defaultValue; const BldCfgOptionDependRaw *depend; const List *allowList; const StringList *roleList; @@ -304,13 +330,12 @@ typedef struct BldCfgOptionRaw const Variant *negate; bool reset; DefaultType defaultType; - const String *defaultValue; + const BldCfgOptionDefaultRaw *defaultValue; const String *group; bool secure; const BldCfgOptionDependRaw *depend; const List *allowList; - const String *allowRangeMin; - const String *allowRangeMax; + const BldCfgOptionAllowRangeRaw *allowRange; const List *cmdList; const StringList *cmdRoleList; const List *deprecateList; @@ -411,26 +436,213 @@ bldCfgParseAllowList(Yaml *const yaml, const List *const optList) } // Helper to parse allow range -static void -bldCfgParseAllowRange(Yaml *const yaml, BldCfgOptionRaw *const opt) +static const BldCfgOptionAllowRange * +bldCfgParseAllowRangeDup(const BldCfgOptionAllowRangeRaw *const allowRangeRaw) { + BldCfgOptionAllowRange *result = NULL; + + if (allowRangeRaw != NULL) + { + result = memNew(sizeof(BldCfgOptionAllowRange)); + *result = (BldCfgOptionAllowRange){0}; + + result->min = strDup(allowRangeRaw->min); + result->max = strDup(allowRangeRaw->max); + + if (allowRangeRaw->mapList != NULL) + { + List *const mapList = lstNewP(sizeof(BldCfgOptionAllowRangeMap), .comparator = lstComparatorStr); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(allowRangeRaw->mapList); mapIdx++) + { + const BldCfgOptionAllowRangeMapRaw *const allowRangeMapRaw = lstGet(allowRangeRaw->mapList, mapIdx); + const BldCfgOptionAllowRangeMap allowRangeMap = + { + .map = strDup(allowRangeMapRaw->map), + .min = strDup(allowRangeMapRaw->min), + .max = strDup(allowRangeMapRaw->max), + }; + + lstAdd(mapList, &allowRangeMap); + } + + result->mapList = mapList; + } + } + + return result; +} + +static const BldCfgOptionAllowRangeRaw * +bldCfgParseAllowRange(Yaml *const yaml) +{ + BldCfgOptionAllowRangeRaw *result = memNew(sizeof(BldCfgOptionAllowRangeRaw)); + *result = (BldCfgOptionAllowRangeRaw){0}; + MEM_CONTEXT_TEMP_BEGIN() { yamlEventNextCheck(yaml, yamlEventTypeSeqBegin); - YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); - YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); - - MEM_CONTEXT_PRIOR_BEGIN() + if (yamlEventPeek(yaml).type == yamlEventTypeScalar) { - opt->allowRangeMin = strDup(allowRangeMinVal.value); - opt->allowRangeMax = strDup(allowRangeMaxVal.value); - } - MEM_CONTEXT_PRIOR_END(); + YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); + YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); - yamlEventNextCheck(yaml, yamlEventTypeSeqEnd); + MEM_CONTEXT_PRIOR_BEGIN() + { + result->min = strDup(allowRangeMinVal.value); + result->max = strDup(allowRangeMaxVal.value); + } + MEM_CONTEXT_PRIOR_END(); + + yamlEventNextCheck(yaml, yamlEventTypeSeqEnd); + } + else + { + YamlEvent allowRangeVal = yamlEventNext(yaml); + + MEM_CONTEXT_PRIOR_BEGIN() + { + result->mapList = lstNewP(sizeof(BldCfgOptionAllowRangeMapRaw)); + } + MEM_CONTEXT_PRIOR_END(); + + do + { + yamlEventCheck(allowRangeVal, yamlEventTypeMapBegin); + + const String *const map = yamlEventNextCheck(yaml, yamlEventTypeScalar).value; + + yamlEventNextCheck(yaml, yamlEventTypeSeqBegin); + + YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); + YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); + + MEM_CONTEXT_PRIOR_BEGIN() + { + const BldCfgOptionAllowRangeMapRaw allowRangeMap = + { + .map = strDup(map), + .min = strDup(allowRangeMinVal.value), + .max = strDup(allowRangeMaxVal.value), + }; + + lstAdd(result->mapList, &allowRangeMap); + } + MEM_CONTEXT_PRIOR_END(); + + yamlEventNextCheck(yaml, yamlEventTypeSeqEnd); + yamlEventNextCheck(yaml, yamlEventTypeMapEnd); + + allowRangeVal = yamlEventNext(yaml); + } + while (allowRangeVal.type != yamlEventTypeSeqEnd); + } } MEM_CONTEXT_TEMP_END(); + + return result; +} + +// Helper to parse default +static const BldCfgOptionDefault * +bldCfgParseDefaultDup(const BldCfgOptionDefaultRaw *const defaultRaw) +{ + BldCfgOptionDefault *result = NULL; + + if (defaultRaw != NULL) + { + result = memNew(sizeof(BldCfgOptionDefault)); + *result = (BldCfgOptionDefault){0}; + result->value = strDup(defaultRaw->value); + + if (defaultRaw->mapList != NULL) + { + List *const mapList = lstNewP(sizeof(BldCfgOptionDefaultMap), .comparator = lstComparatorStr); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultRaw->mapList); mapIdx++) + { + const BldCfgOptionDefaultMapRaw *const defaultMapRaw = lstGet(defaultRaw->mapList, mapIdx); + const BldCfgOptionDefaultMap defaultMap = + { + .map = strDup(defaultMapRaw->map), + .value = strDup(defaultMapRaw->value), + }; + + lstAdd(mapList, &defaultMap); + } + + result->mapList = mapList; + } + } + + return result; +} + +static const BldCfgOptionDefaultRaw * +bldCfgParseDefault(Yaml *const yaml) +{ + BldCfgOptionDefaultRaw *result = memNew(sizeof(BldCfgOptionDefaultRaw)); + *result = (BldCfgOptionDefaultRaw){0}; + + MEM_CONTEXT_TEMP_BEGIN() + { + YamlEvent defaultVal = yamlEventNext(yaml); + + if (defaultVal.type == yamlEventTypeScalar) + { + // If an override to inheritance then set to NULL + if (strEqZ(defaultVal.value, "~")) + result = NULL; + else + { + MEM_CONTEXT_PRIOR_BEGIN() + { + result->value = strDup(defaultVal.value); + } + MEM_CONTEXT_PRIOR_END(); + } + } + else + { + yamlEventCheck(defaultVal, yamlEventTypeSeqBegin); + defaultVal = yamlEventNext(yaml); + + MEM_CONTEXT_PRIOR_BEGIN() + { + result->mapList = lstNewP(sizeof(BldCfgOptionDefaultMapRaw)); + } + MEM_CONTEXT_PRIOR_END(); + + do + { + yamlEventCheck(defaultVal, yamlEventTypeMapBegin); + + const String *const map = yamlEventNextCheck(yaml, yamlEventTypeScalar).value; + const String *const value = yamlEventNextCheck(yaml, yamlEventTypeScalar).value; + + MEM_CONTEXT_PRIOR_BEGIN() + { + const BldCfgOptionDefaultMapRaw defaultMap = + { + .map = strDup(map), + .value = strDup(value), + }; + + lstAdd(result->mapList, &defaultMap); + } + MEM_CONTEXT_PRIOR_END(); + + yamlEventNextCheck(yaml, yamlEventTypeMapEnd); + + defaultVal = yamlEventNext(yaml); + } + while (defaultVal.type != yamlEventTypeSeqEnd); + } + } + MEM_CONTEXT_TEMP_END(); + + return result; } // Helper to parse depend @@ -531,8 +743,11 @@ bldCfgParseDependReconcile( if (optDependRaw != NULL) { - if (optDependRaw->defaultValue != NULL && !strEq(optRaw->type, OPT_TYPE_BOOLEAN_STR)) - THROW_FMT(FormatError, "dependency default invalid for non-boolean option '%s'", strZ(optRaw->name)); + if (optDependRaw->defaultValue != NULL && !strEq(optRaw->type, OPT_TYPE_BOOLEAN_STR) && + !strEq(optRaw->type, OPT_TYPE_INTEGER_STR)) + { + THROW_FMT(FormatError, "dependency default invalid for non integer/boolean option '%s'", strZ(optRaw->name)); + } const BldCfgOption *const optDepend = lstFind(optList, &optDependRaw->option); @@ -686,22 +901,19 @@ bldCfgParseOptionCommandList(Yaml *const yaml, const List *const optList) } MEM_CONTEXT_END(); } + else if (strEqZ(optCmdDef.value, "default")) + { + MEM_CONTEXT_BEGIN(lstMemContext(optCmdRawList)) + { + optCmdRaw.defaultValue = bldCfgParseDefault(yaml); + } + MEM_CONTEXT_END(); + } else { YamlEvent optCmdDefVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); - if (strEqZ(optCmdDef.value, "default")) - { - // If an override to inheritance - if (strEqZ(optCmdDefVal.value, "~")) - { - optCmdRaw.defaultValue = NULL; - } - // Else set the value - else - optCmdRaw.defaultValue = optCmdDefVal.value; - } - else if (strEqZ(optCmdDef.value, "internal")) + if (strEqZ(optCmdDef.value, "internal")) { optCmdRaw.internal = varNewBool(yamlBoolParse(optCmdDefVal)); } @@ -727,7 +939,7 @@ bldCfgParseOptionCommandList(Yaml *const yaml, const List *const optList) .name = strDup(optCmdRaw.name), .internal = varDup(optCmdRaw.internal), .required = varDup(optCmdRaw.required), - .defaultValue = strDup(optCmdRaw.defaultValue), + .defaultValue = optCmdRaw.defaultValue, .depend = optCmdRaw.depend, .allowList = bldCfgParseAllowListDup(optCmdRaw.allowList), .roleList = strLstDup(optCmdRaw.roleList), @@ -798,7 +1010,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c } else if (strEqZ(optDef.value, "allow-range")) { - bldCfgParseAllowRange(yaml, &optRaw); + optRaw.allowRange = bldCfgParseAllowRange(yaml); } else if (strEqZ(optDef.value, "command")) { @@ -808,6 +1020,10 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c { optRaw.cmdRoleList = bldCfgParseCommandRole(yaml); } + else if (strEqZ(optDef.value, "default")) + { + optRaw.defaultValue = bldCfgParseDefault(yaml); + } else if (strEqZ(optDef.value, "depend")) { optRaw.depend = bldCfgParseDepend(yaml, optListRaw); @@ -820,18 +1036,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c { YamlEvent optDefVal = yamlEventNextCheck(yaml, yamlEventTypeScalar); - if (strEqZ(optDef.value, "default")) - { - // If an override to inheritance - if (strEqZ(optDefVal.value, "~")) - { - optRaw.defaultValue = NULL; - } - // Else set the value - else - optRaw.defaultValue = optDefVal.value; - } - else if (strEqZ(optDef.value, "default-type")) + if (strEqZ(optDef.value, "default-type")) { if (strEqZ(optDefVal.value, "quote")) optRaw.defaultType = defaultTypeQuote; @@ -973,12 +1178,11 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c .negate = varBool(optRaw->negate), .reset = optRaw->reset, .defaultType = optRaw->defaultType, - .defaultValue = strDup(optRaw->defaultValue), + .defaultValue = bldCfgParseDefaultDup(optRaw->defaultValue), .group = strDup(optRaw->group), .secure = optRaw->secure, .allowList = bldCfgParseAllowListDup(optRaw->allowList), - .allowRangeMin = strDup(optRaw->allowRangeMin), - .allowRangeMax = strDup(optRaw->allowRangeMax), + .allowRange = bldCfgParseAllowRangeDup(optRaw->allowRange), .deprecateList = bldCfgParseOptionDeprecateReconcile(optRaw->deprecateList), }; @@ -1049,7 +1253,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c .name = strDup(optCmd.name), .internal = varBool(optCmd.internal), .required = varBool(optCmd.required), - .defaultValue = strDup(optCmd.defaultValue), + .defaultValue = bldCfgParseDefaultDup(optCmd.defaultValue), .depend = bldCfgParseDependReconcile(optRaw, optCmd.depend, result), .allowList = bldCfgParseAllowListDup(optCmd.allowList), .roleList = strLstDup(optCmd.roleList), diff --git a/src/build/config/parse.h b/src/build/config/parse.h index 2aded8c33..3cb2cf167 100644 --- a/src/build/config/parse.h +++ b/src/build/config/parse.h @@ -99,6 +99,32 @@ typedef struct BldCfgOptionGroup typedef struct BldCfgOption BldCfgOption; // Forward declaration +typedef struct BldCfgOptionAllowRangeMap +{ + const String *map; // Map value + const String *min; // Min value + const String *max; // Max value +} BldCfgOptionAllowRangeMap; + +typedef struct BldCfgOptionAllowRange +{ + const String *min; // Min value + const String *max; // Max value + const List *mapList; // List of default mappings +} BldCfgOptionAllowRange; + +typedef struct BldCfgOptionDefaultMap +{ + const String *map; // Map value + const String *value; // Default value +} BldCfgOptionDefaultMap; + +typedef struct BldCfgOptionDefault +{ + const String *value; // Default value + const List *mapList; // List of default mappings +} BldCfgOptionDefault; + typedef struct BldCfgOptionDepend { const BldCfgOption *option; // Option dependency is on @@ -118,7 +144,7 @@ typedef struct BldCfgOptionCommand const String *name; // Name bool internal; // Is the option internal? bool required; // Is the option required? - const String *defaultValue; // Default value, if any + const BldCfgOptionDefault *defaultValue; // Default value, if any const BldCfgOptionDepend *depend; // Dependency, if any const List *allowList; // Allowed value list const StringList *roleList; // Roles valid for the command @@ -142,13 +168,12 @@ struct BldCfgOption bool negate; // Can the option be negated? bool reset; // Can the option be reset? DefaultType defaultType; // Type of default - const String *defaultValue; // Default value, if any + const BldCfgOptionDefault *defaultValue; // Default value, if any const String *group; // Option group, if any bool secure; // Does the option contain a secret? const BldCfgOptionDepend *depend; // Dependency, if any const List *allowList; // Allowed value list - const String *allowRangeMin; // Allow range min, if any - const String *allowRangeMax; // Allow range max, if any + const BldCfgOptionAllowRange *allowRange; // Allow range, if any const List *cmdList; // Command override list const List *deprecateList; // List of option deprecations }; diff --git a/src/build/config/render.c b/src/build/config/render.c index fc9fdf83b..82363cc9b 100644 --- a/src/build/config/render.c +++ b/src/build/config/render.c @@ -397,7 +397,7 @@ bldCfgRenderScalar(const String *const scalar, const String *const optType) // Helper to render validity static String * -bldCfgRenderValid(const BldCfgOptionDepend *const depend) +bldCfgRenderValid(const String *const type, const BldCfgOptionDepend *const depend) { ASSERT(depend != NULL); @@ -412,8 +412,7 @@ bldCfgRenderValid(const BldCfgOptionDepend *const depend) { strCatFmt( result, - " PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(%s),\n", - strZ(bldCfgRenderScalar(depend->defaultValue, OPT_TYPE_BOOLEAN_STR))); + " PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(%s),\n", strZ(bldCfgRenderScalar(depend->defaultValue, type))); } strCatFmt( @@ -444,20 +443,57 @@ bldCfgRenderValid(const BldCfgOptionDepend *const depend) // Helper to render allow range static String * -bldCfgRenderAllowRange(const String *const allowRangeMin, const String *const allowRangeMax, const String *const optType) +bldCfgRenderAllowRange(const BldCfgOptionAllowRange *const allowRange, const String *const optType) { - ASSERT(allowRangeMin != NULL); - ASSERT(allowRangeMax != NULL); + ASSERT((allowRange->min != NULL && allowRange->min != NULL) || (allowRange->min == NULL && allowRange->min == NULL)); + ASSERT((allowRange->mapList == NULL && allowRange->min != NULL) || (allowRange->mapList != NULL && allowRange->min == NULL)); ASSERT(optType != NULL); - return strNewFmt( + String *const result = strCatZ( + strNew(), " PARSE_RULE_OPTIONAL_ALLOW_RANGE\n" - " (\n" - " %s,\n" - " %s,\n" - " )", - strZ(bldCfgRenderScalar(allowRangeMin, optType)), - strZ(bldCfgRenderScalar(allowRangeMax, optType))); + " (\n"); + + if (allowRange->mapList != NULL) + { + strCatFmt( + result, + " PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n" + " (\n"); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(allowRange->mapList); mapIdx++) + { + const BldCfgOptionAllowRangeMap *const allowRangeMap = lstGet(allowRange->mapList, mapIdx); + + strCatFmt( + result, + " %s,\n" + " %s,\n" + " %s,\n", + strZ(bldCfgRenderScalar(allowRangeMap->map, OPT_TYPE_STRING_ID_STR)), + strZ(bldCfgRenderScalar(allowRangeMap->min, optType)), + strZ(bldCfgRenderScalar(allowRangeMap->max, optType))); + } + + strCatZ( + result, + " ),\n"); + } + else + { + strCatFmt( + result, + " %s,\n" + " %s,\n", + strZ(bldCfgRenderScalar(allowRange->min, optType)), + strZ(bldCfgRenderScalar(allowRange->max, optType))); + } + + strCatZ( + result, + " )"); + + return result; } // Helper to render allow list @@ -497,9 +533,36 @@ bldCfgRenderAllowList(const List *const allowList, const String *const optType) } // Helper to render default +static void +bldCfgRenderDefaultValue( + String *const result, const String *const defaultValue, const DefaultType defaultType, const String *const optType, + const bool indent) +{ + ASSERT(defaultValue != NULL); + ASSERT(optType != NULL); + + if (indent) + strCatZ(result, " "); + + if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR)) + { + strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType))); + } + else + { + strCatFmt( + result, + " %s,\n", + strZ( + bldCfgRenderScalar( + strNewFmt( + "%s%s%s", defaultType == defaultTypeLiteral ? "" : "\"", strZ(defaultValue), + defaultType == defaultTypeLiteral ? "" : "\""), OPT_TYPE_STRING_STR))); + } +} + static String * -bldCfgRenderDefault( - const String *const defaultValue, const DefaultType defaultType, const String *const optType) +bldCfgRenderDefault(const BldCfgOptionDefault *const defaultValue, const DefaultType defaultType, const String *const optType) { ASSERT(defaultValue != NULL); ASSERT(optType != NULL); @@ -513,20 +576,29 @@ bldCfgRenderDefault( if (defaultType == defaultTypeDynamic) { - strCatFmt(result, " PARSE_RULE_DEFAULT_DYNAMIC(%s),\n", strZ(bldEnum("", defaultValue))); + strCatFmt(result, " PARSE_RULE_DEFAULT_DYNAMIC(%s),\n", strZ(bldEnum("", defaultValue->value))); } - else if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR)) - strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType))); + else if (defaultValue->value != NULL) + bldCfgRenderDefaultValue(result, defaultValue->value, defaultType, optType, false); else { - strCatFmt( + ASSERT(defaultValue->mapList != NULL); + + strCatZ( result, - " %s,\n", - strZ( - bldCfgRenderScalar( - strNewFmt( - "%s%s%s", defaultType == defaultTypeLiteral ? "" : "\"", strZ(defaultValue), - defaultType == defaultTypeLiteral ? "" : "\""), OPT_TYPE_STRING_STR))); + " PARSE_RULE_OPTIONAL_DEFAULT_MAP\n" + " (\n"); + + for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultValue->mapList); mapIdx++) + { + const BldCfgOptionDefaultMap *const map = lstGet(defaultValue->mapList, mapIdx); + + strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(map->map, OPT_TYPE_STRING_ID_STR))); + + bldCfgRenderDefaultValue(result, map->value, defaultType, optType, true); + } + + strCatZ(result, " ),\n"); } strCatZ(result, " )"); @@ -867,7 +939,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co // Build list of dynamic defaults if (opt->defaultType == defaultTypeDynamic) - strLstAddIfMissing(dynamicDefaultList, opt->defaultValue); + strLstAddIfMissing(dynamicDefaultList, opt->defaultValue->value); if (optIdx != 0) strCatZ(config, COMMENT_SEPARATOR "\n"); @@ -972,16 +1044,27 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co const Variant *const ruleList[] = {ruleDepend, ruleAllowRange, ruleAllowList, ruleDefault, ruleRequire}; if (opt->depend) - kvAdd(optionalDefaultRule, ruleDepend, VARSTR(bldCfgRenderValid(opt->depend))); + kvAdd(optionalDefaultRule, ruleDepend, VARSTR(bldCfgRenderValid(opt->type, opt->depend))); - if (opt->allowRangeMin != NULL) + if (opt->allowRange != NULL) { - kvAdd( - optionalDefaultRule, ruleAllowRange, - VARSTR(bldCfgRenderAllowRange(opt->allowRangeMin, opt->allowRangeMax, opt->type))); + kvAdd(optionalDefaultRule, ruleAllowRange, VARSTR(bldCfgRenderAllowRange(opt->allowRange, opt->type))); - bldCfgRenderValueAdd(opt->type, false, opt->allowRangeMin, ruleValMap); - bldCfgRenderValueAdd(opt->type, false, opt->allowRangeMax, ruleValMap); + if (opt->allowRange->mapList != NULL) + { + for (unsigned int mapIdx = 0; mapIdx < lstSize(opt->allowRange->mapList); mapIdx++) + { + const BldCfgOptionAllowRangeMap *const allowRangeMap = lstGet(opt->allowRange->mapList, mapIdx); + + bldCfgRenderValueAdd(opt->type, false, allowRangeMap->min, ruleValMap); + bldCfgRenderValueAdd(opt->type, false, allowRangeMap->max, ruleValMap); + } + } + else + { + bldCfgRenderValueAdd(opt->type, false, opt->allowRange->min, ruleValMap); + bldCfgRenderValueAdd(opt->type, false, opt->allowRange->max, ruleValMap); + } } if (opt->allowList != NULL) @@ -997,10 +1080,24 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co if (opt->defaultValue != NULL) { - kvAdd(optionalDefaultRule, ruleDefault, VARSTR(bldCfgRenderDefault(opt->defaultValue, opt->defaultType, opt->type))); + kvAdd( + optionalDefaultRule, ruleDefault, + VARSTR(bldCfgRenderDefault(opt->defaultValue, opt->defaultType, opt->type))); if (!strEq(opt->type, OPT_TYPE_BOOLEAN_STR)) - bldCfgRenderValueAdd(opt->type, opt->defaultType, opt->defaultValue, ruleValMap); + { + if (opt->defaultValue->value != NULL) + bldCfgRenderValueAdd(opt->type, opt->defaultType, opt->defaultValue->value, ruleValMap); + + if (opt->defaultValue->mapList != NULL) + { + for (unsigned int mapIdx = 0; mapIdx < lstSize(opt->defaultValue->mapList); mapIdx++) + { + const BldCfgOptionDefaultMap *const map = lstGet(opt->defaultValue->mapList, mapIdx); + bldCfgRenderValueAdd(opt->type, opt->defaultType, map->value, ruleValMap); + } + } + } } // Build command optional rules @@ -1013,7 +1110,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co // Depends if (optCmd->depend != NULL) - kvAdd(optionalCmdRuleType, ruleDepend, VARSTR(bldCfgRenderValid(optCmd->depend))); + kvAdd(optionalCmdRuleType, ruleDepend, VARSTR(bldCfgRenderValid(opt->type, optCmd->depend))); // Allow lists if (optCmd->allowList != NULL) @@ -1035,7 +1132,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co VARSTR(bldCfgRenderDefault(optCmd->defaultValue, opt->defaultType, opt->type))); if (!strEq(opt->type, OPT_TYPE_BOOLEAN_STR)) - bldCfgRenderValueAdd(opt->type, opt->defaultType, optCmd->defaultValue, ruleValMap); + bldCfgRenderValueAdd(opt->type, opt->defaultType, optCmd->defaultValue->value, ruleValMap); } // Requires diff --git a/src/build/help/help.xml b/src/build/help/help.xml index 490664aac..1235d6ae0 100644 --- a/src/build/help/help.xml +++ b/src/build/help/help.xml @@ -230,15 +230,6 @@

Sets the level to be used for file compression when compress-type does not equal none or compress=y (deprecated).

- -

The following are the defaults levels based on compress-type when compress-level is not specified:

- - - bz2 - 9 - gz - 6 - lz4 - 1 - zst - 3 -
0-9 @@ -848,6 +839,8 @@

Use this option to specify a non-default port for the repository host protocol.

+ + When repo-host-type=ssh there is no default for repo-host-port. In this case the port will be whatever is configured for the command specified by cmd-ssh.
25 @@ -1263,14 +1256,6 @@

A larger chunk size will generally lead to better performance because it will minimize upload requests and allow more files to be uploaded in a single request rather than in chunks. The disadvantage is that memory usage will be higher and because the chunk buffer must be allocated per process, larger process-max values will lead to more memory being consumed overall.

-

Default chunk sizes by repo type:

- - - azure - 4MiB - gcs - 4MiB - s3 - 5MiB - -

Note that valid chunk sizes vary by storage type and by platform. For example, AWS S3 has a minimum chunk size of 5MiB but S3 clones may accept lower values. Terminology for chunk size varies by storage type, so when searching min/max values use part size for AWS S3, chunk size for GCS, and block size for Azure. No attempt is made to validate configured chunk sizes so selecting an invalid value will lead to errors from the storage service or undefined behavior.

@@ -1974,6 +1959,8 @@

Use this option to specify a non-default port for the host protocol.

+ + When pg-host-type=ssh there is no default for pg-host-port. In this case the port will be whatever is configured for the command specified by cmd-ssh.
25 diff --git a/src/common/compress/bz2/compress.h b/src/common/compress/bz2/compress.h index bfa9bda8c..72c2ea6e1 100644 --- a/src/common/compress/bz2/compress.h +++ b/src/common/compress/bz2/compress.h @@ -16,7 +16,6 @@ Filter type constant /*********************************************************************************************************************************** Level constants ***********************************************************************************************************************************/ -#define BZ2_COMPRESS_LEVEL_DEFAULT 9 #define BZ2_COMPRESS_LEVEL_MIN 1 #define BZ2_COMPRESS_LEVEL_MAX 9 diff --git a/src/common/compress/gz/compress.h b/src/common/compress/gz/compress.h index 4a0e2eecd..94156337f 100644 --- a/src/common/compress/gz/compress.h +++ b/src/common/compress/gz/compress.h @@ -16,7 +16,6 @@ Filter type constant /*********************************************************************************************************************************** Level constants ***********************************************************************************************************************************/ -#define GZ_COMPRESS_LEVEL_DEFAULT 6 #define GZ_COMPRESS_LEVEL_MIN -1 #define GZ_COMPRESS_LEVEL_MAX 9 diff --git a/src/common/compress/helper.c b/src/common/compress/helper.c index 11604d654..13075fc6d 100644 --- a/src/common/compress/helper.c +++ b/src/common/compress/helper.c @@ -12,7 +12,6 @@ Compression Helper #include "common/compress/gz/compress.h" #include "common/compress/gz/decompress.h" #include "common/compress/helper.h" -#include "common/compress/helper.intern.h" #include "common/compress/lz4/common.h" #include "common/compress/lz4/compress.h" #include "common/compress/lz4/decompress.h" @@ -43,9 +42,6 @@ static const struct CompressHelperLocal IoFilter *(*compressNew)(int, bool); // Function to create new compression filter StringId decompressType; // Type of the decompression filter IoFilter *(*decompressNew)(bool); // Function to create new decompression filter - int levelDefault : 8; // Default compression level - int levelMin : 8; // Minimum compression level - int levelMax : 8; // Maximum compression level } compressHelperLocal[] = { { @@ -61,9 +57,6 @@ static const struct CompressHelperLocal .compressNew = bz2CompressNew, .decompressType = BZ2_DECOMPRESS_FILTER_TYPE, .decompressNew = bz2DecompressNew, - .levelDefault = BZ2_COMPRESS_LEVEL_DEFAULT, - .levelMin = BZ2_COMPRESS_LEVEL_MIN, - .levelMax = BZ2_COMPRESS_LEVEL_MAX, }, { .typeId = STRID5("gz", 0x3470), @@ -73,9 +66,6 @@ static const struct CompressHelperLocal .compressNew = gzCompressNew, .decompressType = GZ_DECOMPRESS_FILTER_TYPE, .decompressNew = gzDecompressNew, - .levelDefault = GZ_COMPRESS_LEVEL_DEFAULT, - .levelMin = GZ_COMPRESS_LEVEL_MIN, - .levelMax = GZ_COMPRESS_LEVEL_MAX, }, { .typeId = STRID6("lz4", 0x2068c1), @@ -85,9 +75,6 @@ static const struct CompressHelperLocal .compressNew = lz4CompressNew, .decompressType = LZ4_DECOMPRESS_FILTER_TYPE, .decompressNew = lz4DecompressNew, - .levelDefault = LZ4_COMPRESS_LEVEL_DEFAULT, - .levelMin = LZ4_COMPRESS_LEVEL_MIN, - .levelMax = LZ4_COMPRESS_LEVEL_MAX, }, { .typeId = STRID5("zst", 0x527a0), @@ -98,9 +85,6 @@ static const struct CompressHelperLocal .compressNew = zstCompressNew, .decompressType = ZST_DECOMPRESS_FILTER_TYPE, .decompressNew = zstDecompressNew, - .levelDefault = ZST_COMPRESS_LEVEL_DEFAULT, - .levelMin = ZST_COMPRESS_LEVEL_MIN, - .levelMax = ZST_COMPRESS_LEVEL_MAX, #endif }, { @@ -185,48 +169,6 @@ compressTypeFromName(const String *const name) FUNCTION_TEST_RETURN(ENUM, result); } -/**********************************************************************************************************************************/ -FN_EXTERN int -compressLevelDefault(const CompressType type) -{ - FUNCTION_TEST_BEGIN(); - FUNCTION_TEST_PARAM(ENUM, type); - FUNCTION_TEST_END(); - - ASSERT(type < LENGTH_OF(compressHelperLocal)); - compressTypePresent(type); - - FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelDefault); -} - -/**********************************************************************************************************************************/ -FN_EXTERN int -compressLevelMin(const CompressType type) -{ - FUNCTION_TEST_BEGIN(); - FUNCTION_TEST_PARAM(ENUM, type); - FUNCTION_TEST_END(); - - ASSERT(type < LENGTH_OF(compressHelperLocal)); - compressTypePresent(type); - - FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelMin); -} - -/**********************************************************************************************************************************/ -FN_EXTERN int -compressLevelMax(const CompressType type) -{ - FUNCTION_TEST_BEGIN(); - FUNCTION_TEST_PARAM(ENUM, type); - FUNCTION_TEST_END(); - - ASSERT(type < LENGTH_OF(compressHelperLocal)); - compressTypePresent(type); - - FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelMax); -} - /**********************************************************************************************************************************/ FN_EXTERN IoFilter * compressFilter(const CompressType type, const int level, const CompressFilterParam param) diff --git a/src/common/compress/helper.intern.h b/src/common/compress/helper.intern.h deleted file mode 100644 index cbf299e81..000000000 --- a/src/common/compress/helper.intern.h +++ /dev/null @@ -1,21 +0,0 @@ -/*********************************************************************************************************************************** -Compression Helper Internal -***********************************************************************************************************************************/ -#ifndef COMMON_COMPRESS_HELPER_INTERN_H -#define COMMON_COMPRESS_HELPER_INTERN_H - -#include "common/compress/helper.h" - -/*********************************************************************************************************************************** -Functions -***********************************************************************************************************************************/ -// Default compression level for a compression type, used while loading the configuration -FN_EXTERN int compressLevelDefault(CompressType type); - -// Minimum compression level for a compression type, used while loading the configuration -FN_EXTERN int compressLevelMin(CompressType type); - -// Maximum compression level for a compression type, used while loading the configuration -FN_EXTERN int compressLevelMax(CompressType type); - -#endif diff --git a/src/common/compress/lz4/compress.h b/src/common/compress/lz4/compress.h index 2ef671d33..23131e5df 100644 --- a/src/common/compress/lz4/compress.h +++ b/src/common/compress/lz4/compress.h @@ -16,7 +16,6 @@ Filter type constant /*********************************************************************************************************************************** Level constants ***********************************************************************************************************************************/ -#define LZ4_COMPRESS_LEVEL_DEFAULT 1 #define LZ4_COMPRESS_LEVEL_MIN -5 #define LZ4_COMPRESS_LEVEL_MAX 12 diff --git a/src/common/compress/zst/compress.h b/src/common/compress/zst/compress.h index e3c3c09c0..8bbb046b8 100644 --- a/src/common/compress/zst/compress.h +++ b/src/common/compress/zst/compress.h @@ -18,7 +18,6 @@ Filter type constant /*********************************************************************************************************************************** Level constants ***********************************************************************************************************************************/ -#define ZST_COMPRESS_LEVEL_DEFAULT 3 #define ZST_COMPRESS_LEVEL_MIN -7 #define ZST_COMPRESS_LEVEL_MAX 22 diff --git a/src/config/load.c b/src/config/load.c index 4fbc2472b..da84b4367 100644 --- a/src/config/load.c +++ b/src/config/load.c @@ -9,7 +9,6 @@ Configuration Load #include "command/command.h" #include "command/lock.h" -#include "common/compress/helper.intern.h" #include "common/crypto/common.h" #include "common/debug.h" #include "common/io/io.h" @@ -289,48 +288,6 @@ cfgLoadUpdateOption(void) } } - // Set default upload chunk size if not set - if (cfgOptionValid(cfgOptRepoStorageUploadChunkSize)) - { - for (unsigned int repoIdx = 0; repoIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); repoIdx++) - { - if (!cfgOptionIdxTest(cfgOptRepoStorageUploadChunkSize, repoIdx)) - { - cfgOptionIdxSet( - cfgOptRepoStorageUploadChunkSize, repoIdx, cfgSourceDefault, - VARINT64((cfgOptionIdxStrId(cfgOptRepoType, repoIdx) == CFGOPTVAL_REPO_TYPE_S3 ? 5 : 4) * 1024 * 1024)); - } - } - } - - // Set pg-host-port/repo-host-port default when pg-host-type/repo-host-type is tls. ??? This should be handled in the parser but - // it requires a default that depends on another option value and that is not currently possible. - #define HOST_PORT_TLS 8432 - - if (cfgOptionValid(cfgOptRepoHostPort)) - { - for (unsigned int repoIdx = 0; repoIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); repoIdx++) - { - if (cfgOptionIdxStrId(cfgOptRepoHostType, repoIdx) == CFGOPTVAL_REPO_HOST_TYPE_TLS && - cfgOptionIdxSource(cfgOptRepoHostPort, repoIdx) == cfgSourceDefault) - { - cfgOptionIdxSet(cfgOptRepoHostPort, repoIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS)); - } - } - } - - if (cfgOptionValid(cfgOptPgHostPort)) - { - for (unsigned int pgIdx = 0; pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); pgIdx++) - { - if (cfgOptionIdxStrId(cfgOptPgHostType, pgIdx) == CFGOPTVAL_PG_HOST_TYPE_TLS && - cfgOptionIdxSource(cfgOptPgHostPort, pgIdx) == cfgSourceDefault) - { - cfgOptionIdxSet(cfgOptPgHostPort, pgIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS)); - } - } - } - // Check/update compress-type if compress is valid. There should be no references to the compress option outside this block. if (cfgOptionValid(cfgOptCompress)) { @@ -346,7 +303,10 @@ cfgLoadUpdateOption(void) // Set compress-type to none. Eventually the compress option will be deprecated and removed so this reduces code churn // when that happens. if (!cfgOptionBool(cfgOptCompress) && cfgOptionSource(cfgOptCompressType) == cfgSourceDefault) + { cfgOptionSet(cfgOptCompressType, cfgSourceParam, VARUINT64(CFGOPTVAL_COMPRESS_TYPE_NONE)); + cfgOptionSet(cfgOptCompressLevel, cfgSourceDefault, VARINT64(0)); + } } // Now invalidate compress so it can't be used and won't be passed to child processes @@ -354,29 +314,7 @@ cfgLoadUpdateOption(void) cfgOptionSet(cfgOptCompress, cfgSourceDefault, NULL); } - // Update compress-level default based on the compression type. Also check that level range is valid per compression type. - if (cfgOptionValid(cfgOptCompressLevel)) - { - const CompressType compressType = compressTypeEnum(cfgOptionStrId(cfgOptCompressType)); - - if (cfgOptionSource(cfgOptCompressLevel) == cfgSourceDefault) - { - cfgOptionSet(cfgOptCompressLevel, cfgSourceDefault, VARINT64(compressLevelDefault(compressType))); - } - else if (compressType != compressTypeNone) - { - if (cfgOptionInt(cfgOptCompressLevel) < compressLevelMin(compressType) || - cfgOptionInt(cfgOptCompressLevel) > compressLevelMax(compressType)) - { - THROW_FMT( - OptionInvalidValueError, - "'%d' is out of range for '" CFGOPT_COMPRESS_LEVEL "' option when '" CFGOPT_COMPRESS_TYPE "' option = '%s'", - cfgOptionInt(cfgOptCompressLevel), strZ(strIdToStr(cfgOptionStrId(cfgOptCompressType)))); - } - } - } - - // Error if repo-sftp-host-key-check-type is explicitly set to anything other than fingerprint and repo-sftp-host-fingerprint + // Error if repo-sftp--host-key-check-type is explicitly set to anything other than fingerprint and repo-sftp-host-fingerprint // is also specified. For backward compatibility we need to allow repo-sftp-host-fingerprint when // repo-sftp-host-key-check-type defaults to yes, but emit a warning to let the user know to change the configuration. Also // set repo-sftp-host-key-check-type=fingerprint so other code does not need to know about this exception. diff --git a/src/config/parse.auto.c.inc b/src/config/parse.auto.c.inc index 4549b9dea..992720190 100644 --- a/src/config/parse.auto.c.inc +++ b/src/config/parse.auto.c.inc @@ -11,7 +11,9 @@ Rule Strings static const StringPubConst parseRuleValueStr[] = { + PARSE_RULE_STRPUB("-1"), // val/str PARSE_RULE_STRPUB("-5"), // val/str + PARSE_RULE_STRPUB("-7"), // val/str PARSE_RULE_STRPUB("/tmp/pgbackrest"), // val/str PARSE_RULE_STRPUB("/var/lib/pgbackrest"), // val/str PARSE_RULE_STRPUB("/var/log/pgbackrest"), // val/str @@ -43,6 +45,7 @@ static const StringPubConst parseRuleValueStr[] = PARSE_RULE_STRPUB("256"), // val/str PARSE_RULE_STRPUB("256KiB"), // val/str PARSE_RULE_STRPUB("2MiB"), // val/str + PARSE_RULE_STRPUB("3"), // val/str PARSE_RULE_STRPUB("30m"), // val/str PARSE_RULE_STRPUB("31m"), // val/str PARSE_RULE_STRPUB("32"), // val/str @@ -54,12 +57,15 @@ static const StringPubConst parseRuleValueStr[] = PARSE_RULE_STRPUB("4PiB"), // val/str PARSE_RULE_STRPUB("512KiB"), // val/str PARSE_RULE_STRPUB("5432"), // val/str + PARSE_RULE_STRPUB("5MiB"), // val/str + PARSE_RULE_STRPUB("6"), // val/str PARSE_RULE_STRPUB("64KiB"), // val/str PARSE_RULE_STRPUB("65535"), // val/str PARSE_RULE_STRPUB("7d"), // val/str PARSE_RULE_STRPUB("8432"), // val/str PARSE_RULE_STRPUB("8KiB"), // val/str PARSE_RULE_STRPUB("8MiB"), // val/str + PARSE_RULE_STRPUB("9"), // val/str PARSE_RULE_STRPUB("900"), // val/str PARSE_RULE_STRPUB("999"), // val/str PARSE_RULE_STRPUB("9999999"), // val/str @@ -136,7 +142,9 @@ static const StringPubConst parseRuleValueStr[] = typedef enum { + parseRuleValStrQT_DS_1_QT, // val/str/enum parseRuleValStrQT_DS_5_QT, // val/str/enum + parseRuleValStrQT_DS_7_QT, // val/str/enum parseRuleValStrQT_FS_tmp_FS_pgbackrest_QT, // val/str/enum parseRuleValStrQT_FS_var_FS_lib_FS_pgbackrest_QT, // val/str/enum parseRuleValStrQT_FS_var_FS_log_FS_pgbackrest_QT, // val/str/enum @@ -168,6 +176,7 @@ typedef enum parseRuleValStrQT_256_QT, // val/str/enum parseRuleValStrQT_256KiB_QT, // val/str/enum parseRuleValStrQT_2MiB_QT, // val/str/enum + parseRuleValStrQT_3_QT, // val/str/enum parseRuleValStrQT_30m_QT, // val/str/enum parseRuleValStrQT_31m_QT, // val/str/enum parseRuleValStrQT_32_QT, // val/str/enum @@ -179,12 +188,15 @@ typedef enum parseRuleValStrQT_4PiB_QT, // val/str/enum parseRuleValStrQT_512KiB_QT, // val/str/enum parseRuleValStrQT_5432_QT, // val/str/enum + parseRuleValStrQT_5MiB_QT, // val/str/enum + parseRuleValStrQT_6_QT, // val/str/enum parseRuleValStrQT_64KiB_QT, // val/str/enum parseRuleValStrQT_65535_QT, // val/str/enum parseRuleValStrQT_7d_QT, // val/str/enum parseRuleValStrQT_8432_QT, // val/str/enum parseRuleValStrQT_8KiB_QT, // val/str/enum parseRuleValStrQT_8MiB_QT, // val/str/enum + parseRuleValStrQT_9_QT, // val/str/enum parseRuleValStrQT_900_QT, // val/str/enum parseRuleValStrQT_999_QT, // val/str/enum parseRuleValStrQT_9999999_QT, // val/str/enum @@ -463,10 +475,15 @@ Rule Ints static const int parseRuleValueInt[] = { + -7, // val/int -5, // val/int + -1, // val/int 0, // val/int 1, // val/int 2, // val/int + 3, // val/int + 6, // val/int + 9, // val/int 12, // val/int 22, // val/int 32, // val/int @@ -485,10 +502,15 @@ static const int parseRuleValueInt[] = static const uint8_t parseRuleValueIntStrMap[] = { + parseRuleValStrQT_DS_7_QT, // val/int/strmap parseRuleValStrQT_DS_5_QT, // val/int/strmap + parseRuleValStrQT_DS_1_QT, // val/int/strmap parseRuleValStrQT_0_QT, // val/int/strmap parseRuleValStrQT_1_QT, // val/int/strmap parseRuleValStrQT_2_QT, // val/int/strmap + parseRuleValStrQT_3_QT, // val/int/strmap + parseRuleValStrQT_6_QT, // val/int/strmap + parseRuleValStrQT_9_QT, // val/int/strmap parseRuleValStrQT_12_QT, // val/int/strmap parseRuleValStrQT_22_QT, // val/int/strmap parseRuleValStrQT_32_QT, // val/int/strmap @@ -507,10 +529,15 @@ static const uint8_t parseRuleValueIntStrMap[] = typedef enum { + parseRuleValIntDS_7, // val/int/enum parseRuleValIntDS_5, // val/int/enum + parseRuleValIntDS_1, // val/int/enum parseRuleValInt0, // val/int/enum parseRuleValInt1, // val/int/enum parseRuleValInt2, // val/int/enum + parseRuleValInt3, // val/int/enum + parseRuleValInt6, // val/int/enum + parseRuleValInt9, // val/int/enum parseRuleValInt12, // val/int/enum parseRuleValInt22, // val/int/enum parseRuleValInt32, // val/int/enum @@ -546,6 +573,7 @@ static const int64_t parseRuleValueSize[] = 1048576, // val/size 2097152, // val/size 4194304, // val/size + 5242880, // val/size 8388608, // val/size 16777216, // val/size 20971520, // val/size @@ -570,6 +598,7 @@ static const uint8_t parseRuleValueSizeStrMap[] = parseRuleValStrQT_1MiB_QT, // val/size/strmap parseRuleValStrQT_2MiB_QT, // val/size/strmap parseRuleValStrQT_4MiB_QT, // val/size/strmap + parseRuleValStrQT_5MiB_QT, // val/size/strmap parseRuleValStrQT_8MiB_QT, // val/size/strmap parseRuleValStrQT_16MiB_QT, // val/size/strmap parseRuleValStrQT_20MiB_QT, // val/size/strmap @@ -594,6 +623,7 @@ typedef enum parseRuleValSize1MiB, // val/size/enum parseRuleValSize2MiB, // val/size/enum parseRuleValSize4MiB, // val/size/enum + parseRuleValSize5MiB, // val/size/enum parseRuleValSize8MiB, // val/size/enum parseRuleValSize16MiB, // val/size/enum parseRuleValSize20MiB, // val/size/enum @@ -1821,6 +1851,56 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] = PARSE_RULE_OPTION_COMMAND_ROLE_ASYNC_VALID_LIST // opt/compress-level ( // opt/compress-level PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/compress-level + ), // opt/compress-level + // opt/compress-level + PARSE_RULE_OPTIONAL // opt/compress-level + ( // opt/compress-level + PARSE_RULE_OPTIONAL_GROUP // opt/compress-level + ( // opt/compress-level + PARSE_RULE_OPTIONAL_DEPEND // opt/compress-level + ( // opt/compress-level + PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_INT(0)), // opt/compress-level + PARSE_RULE_VAL_OPT(CompressType), // opt/compress-level + PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level + PARSE_RULE_VAL_STRID(Gz), // opt/compress-level + PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level + PARSE_RULE_VAL_STRID(Zst), // opt/compress-level + ), // opt/compress-level + // opt/compress-level + PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/compress-level + ( // opt/compress-level + PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP // opt/compress-level + ( // opt/compress-level + PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level + PARSE_RULE_VAL_INT(1), // opt/compress-level + PARSE_RULE_VAL_INT(9), // opt/compress-level + PARSE_RULE_VAL_STRID(Gz), // opt/compress-level + PARSE_RULE_VAL_INT(DS_1), // opt/compress-level + PARSE_RULE_VAL_INT(9), // opt/compress-level + PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level + PARSE_RULE_VAL_INT(DS_5), // opt/compress-level + PARSE_RULE_VAL_INT(12), // opt/compress-level + PARSE_RULE_VAL_STRID(Zst), // opt/compress-level + PARSE_RULE_VAL_INT(DS_7), // opt/compress-level + PARSE_RULE_VAL_INT(22), // opt/compress-level + ), // opt/compress-level + ), // opt/compress-level + // opt/compress-level + PARSE_RULE_OPTIONAL_DEFAULT // opt/compress-level + ( // opt/compress-level + PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/compress-level + ( // opt/compress-level + PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level + PARSE_RULE_VAL_INT(9), // opt/compress-level + PARSE_RULE_VAL_STRID(Gz), // opt/compress-level + PARSE_RULE_VAL_INT(6), // opt/compress-level + PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level + PARSE_RULE_VAL_INT(1), // opt/compress-level + PARSE_RULE_VAL_STRID(Zst), // opt/compress-level + PARSE_RULE_VAL_INT(3), // opt/compress-level + ), // opt/compress-level + ), // opt/compress-level + ), // opt/compress-level ), // opt/compress-level ), // opt/compress-level // ----------------------------------------------------------------------------------------------------------------------------- @@ -4138,13 +4218,24 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] = ( // opt/pg-host-port PARSE_RULE_OPTIONAL_DEPEND // opt/pg-host-port ( // opt/pg-host-port - PARSE_RULE_VAL_OPT(PgHost), // opt/pg-host-port + PARSE_RULE_VAL_OPT(PgHostType), // opt/pg-host-port + PARSE_RULE_VAL_STRID(Ssh), // opt/pg-host-port + PARSE_RULE_VAL_STRID(Tls), // opt/pg-host-port ), // opt/pg-host-port // opt/pg-host-port PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/pg-host-port ( // opt/pg-host-port PARSE_RULE_VAL_INT(0), // opt/pg-host-port PARSE_RULE_VAL_INT(65535), // opt/pg-host-port + ), // opt/pg-host-port + // opt/pg-host-port + PARSE_RULE_OPTIONAL_DEFAULT // opt/pg-host-port + ( // opt/pg-host-port + PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/pg-host-port + ( // opt/pg-host-port + PARSE_RULE_VAL_STRID(Tls), // opt/pg-host-port + PARSE_RULE_VAL_INT(8432), // opt/pg-host-port + ), // opt/pg-host-port ), // opt/pg-host-port ), // opt/pg-host-port ), // opt/pg-host-port @@ -6955,13 +7046,24 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] = ( // opt/repo-host-port PARSE_RULE_OPTIONAL_DEPEND // opt/repo-host-port ( // opt/repo-host-port - PARSE_RULE_VAL_OPT(RepoHost), // opt/repo-host-port + PARSE_RULE_VAL_OPT(RepoHostType), // opt/repo-host-port + PARSE_RULE_VAL_STRID(Ssh), // opt/repo-host-port + PARSE_RULE_VAL_STRID(Tls), // opt/repo-host-port ), // opt/repo-host-port // opt/repo-host-port PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/repo-host-port ( // opt/repo-host-port PARSE_RULE_VAL_INT(0), // opt/repo-host-port PARSE_RULE_VAL_INT(65535), // opt/repo-host-port + ), // opt/repo-host-port + // opt/repo-host-port + PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-host-port + ( // opt/repo-host-port + PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/repo-host-port + ( // opt/repo-host-port + PARSE_RULE_VAL_STRID(Tls), // opt/repo-host-port + PARSE_RULE_VAL_INT(8432), // opt/repo-host-port + ), // opt/repo-host-port ), // opt/repo-host-port ), // opt/repo-host-port ), // opt/repo-host-port @@ -9722,6 +9824,19 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] = ( // opt/repo-storage-upload-chunk-size PARSE_RULE_VAL_SIZE(64KiB), // opt/repo-storage-upload-chunk-size PARSE_RULE_VAL_SIZE(1TiB), // opt/repo-storage-upload-chunk-size + ), // opt/repo-storage-upload-chunk-size + // opt/repo-storage-upload-chunk-size + PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-storage-upload-chunk-size + ( // opt/repo-storage-upload-chunk-size + PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/repo-storage-upload-chunk-size + ( // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_STRID(Azure), // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_SIZE(4MiB), // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_STRID(Gcs), // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_SIZE(4MiB), // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_STRID(S3), // opt/repo-storage-upload-chunk-size + PARSE_RULE_VAL_SIZE(5MiB), // opt/repo-storage-upload-chunk-size + ), // opt/repo-storage-upload-chunk-size ), // opt/repo-storage-upload-chunk-size ), // opt/repo-storage-upload-chunk-size ), // opt/repo-storage-upload-chunk-size @@ -11377,7 +11492,6 @@ static const uint8_t optionResolveOrder[] = cfgOptCmd, // opt-resolve-order cfgOptCmdSsh, // opt-resolve-order cfgOptCompress, // opt-resolve-order - cfgOptCompressLevel, // opt-resolve-order cfgOptCompressLevelNetwork, // opt-resolve-order cfgOptCompressType, // opt-resolve-order cfgOptConfig, // opt-resolve-order @@ -11469,6 +11583,7 @@ static const uint8_t optionResolveOrder[] = cfgOptArchiveCheck, // opt-resolve-order cfgOptArchiveCopy, // opt-resolve-order cfgOptArchiveModeCheck, // opt-resolve-order + cfgOptCompressLevel, // opt-resolve-order cfgOptForce, // opt-resolve-order cfgOptPgDatabase, // opt-resolve-order cfgOptPgHost, // opt-resolve-order @@ -11476,7 +11591,6 @@ static const uint8_t optionResolveOrder[] = cfgOptPgHostConfig, // opt-resolve-order cfgOptPgHostConfigIncludePath, // opt-resolve-order cfgOptPgHostConfigPath, // opt-resolve-order - cfgOptPgHostPort, // opt-resolve-order cfgOptPgHostType, // opt-resolve-order cfgOptPgHostUser, // opt-resolve-order cfgOptRecoveryOption, // opt-resolve-order @@ -11499,7 +11613,6 @@ static const uint8_t optionResolveOrder[] = cfgOptRepoHostConfig, // opt-resolve-order cfgOptRepoHostConfigIncludePath, // opt-resolve-order cfgOptRepoHostConfigPath, // opt-resolve-order - cfgOptRepoHostPort, // opt-resolve-order cfgOptRepoHostType, // opt-resolve-order cfgOptRepoHostUser, // opt-resolve-order cfgOptRepoS3Bucket, // opt-resolve-order @@ -11536,6 +11649,7 @@ static const uint8_t optionResolveOrder[] = cfgOptPgHostCaPath, // opt-resolve-order cfgOptPgHostCertFile, // opt-resolve-order cfgOptPgHostKeyFile, // opt-resolve-order + cfgOptPgHostPort, // opt-resolve-order cfgOptRepoGcsBucket, // opt-resolve-order cfgOptRepoGcsEndpoint, // opt-resolve-order cfgOptRepoGcsKey, // opt-resolve-order @@ -11543,6 +11657,7 @@ static const uint8_t optionResolveOrder[] = cfgOptRepoHostCaPath, // opt-resolve-order cfgOptRepoHostCertFile, // opt-resolve-order cfgOptRepoHostKeyFile, // opt-resolve-order + cfgOptRepoHostPort, // opt-resolve-order cfgOptRepoS3Key, // opt-resolve-order cfgOptRepoS3KeySecret, // opt-resolve-order cfgOptRepoSftpHostFingerprint, // opt-resolve-order diff --git a/src/config/parse.c b/src/config/parse.c index 311f71093..de775281c 100644 --- a/src/config/parse.c +++ b/src/config/parse.c @@ -252,13 +252,17 @@ typedef enum #define PARSE_RULE_OPTIONAL_DEPEND(...) \ PARSE_RULE_U32_1(parseRuleOptionalTypeValid), PARSE_RULE_PACK_SIZE(__VA_ARGS__) -#define PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(value) value +#define PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(value) PARSE_RULE_BOOL_TRUE, value #define PARSE_RULE_OPTIONAL_ALLOW_LIST(...) \ PARSE_RULE_U32_1(parseRuleOptionalTypeAllowList), PARSE_RULE_PACK_SIZE(__VA_ARGS__) #define PARSE_RULE_OPTIONAL_ALLOW_RANGE(...) \ PARSE_RULE_U32_1(parseRuleOptionalTypeAllowRange), PARSE_RULE_PACK_SIZE(__VA_ARGS__) +#define PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP(...) \ + 0x10, __VA_ARGS__ 0x00 #define PARSE_RULE_OPTIONAL_DEFAULT(...) \ PARSE_RULE_U32_1(parseRuleOptionalTypeDefault), PARSE_RULE_PACK_SIZE(__VA_ARGS__) +#define PARSE_RULE_OPTIONAL_DEFAULT_MAP(...) \ + 0x10, __VA_ARGS__ 0x00 #define PARSE_RULE_OPTIONAL_REQUIRED(...) \ PARSE_RULE_U32_1(parseRuleOptionalTypeRequired), PARSE_RULE_PACK_SIZE(__VA_ARGS__) #define PARSE_RULE_OPTIONAL_NOT_REQUIRED(...) PARSE_RULE_OPTIONAL_REQUIRED(__VA_ARGS__) @@ -889,6 +893,65 @@ cfgParseOptionValue(const ConfigOptionType type, unsigned int valueIdx) FUNCTION_TEST_RETURN(INT64, parseRuleValueTime[valueIdx]); } +/*********************************************************************************************************************************** +Get default value from pack +***********************************************************************************************************************************/ +static void +cfgParseOptionValuePack(PackRead *const ruleData, const ConfigOptionType type, ConfigOptionValueType *value, const String **raw) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(PACK_READ, ruleData); + FUNCTION_TEST_PARAM(ENUM, type); + FUNCTION_TEST_PARAM_P(VOID, value); + FUNCTION_TEST_PARAM_PP(VOID, raw); + FUNCTION_TEST_END(); + + switch (pckReadType(ruleData)) + { + case pckTypeBool: + { + value->boolean = pckReadBoolP(ruleData); + + if (raw != NULL) + *raw = value->boolean ? Y_STR : N_STR; + + break; + } + + default: + { + const unsigned int valueIdx = pckReadU32P(ruleData); + + switch (type) + { + case cfgOptTypeInteger: + case cfgOptTypeSize: + case cfgOptTypeTime: + value->integer = cfgParseOptionValue(type, valueIdx); + break; + + case cfgOptTypePath: + case cfgOptTypeString: + value->string = cfgParseOptionValueStr(type, valueIdx); + break; + + default: + { + ASSERT(type == cfgOptTypeStringId); + + value->stringId = parseRuleValueStrId[valueIdx]; + break; + } + } + + if (raw != NULL) + *raw = cfgParseOptionValueStr(type, valueIdx); + } + } + + FUNCTION_TEST_RETURN_VOID(); +} + /*********************************************************************************************************************************** Find an optional rule ***********************************************************************************************************************************/ @@ -901,12 +964,14 @@ typedef struct CfgParseOptionalRuleState // Valid const uint8_t *valid; size_t validSize; + unsigned int matchValue; // Allow range int64_t allowRangeMin; int64_t allowRangeMax; unsigned int allowRangeMinIdx; unsigned int allowRangeMaxIdx; + bool allowRangeMatch; // Allow list const uint8_t *allowList; @@ -940,6 +1005,7 @@ cfgParseOptionalRule( ASSERT(optionId < CFG_OPTION_TOTAL); bool result = false; + bool match = false; // Check for optional rules const ParseRuleOption *const ruleOption = &parseRuleOption[optionId]; @@ -1038,8 +1104,9 @@ cfgParseOptionalRule( // If this is the requested optional rule if (optionalRules->typeNext == optionalRuleType) { - // Optional rule was found + // Optional rule was found and dependency was matched result = true; + match = true; // Process optional rule switch (optionalRuleType) @@ -1070,8 +1137,33 @@ cfgParseOptionalRule( { PackRead *const ruleData = pckReadPackReadConstP(optionalRules->pack); - optionalRules->allowRangeMinIdx = pckReadU32P(ruleData); - optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData); + pckReadNext(ruleData); + + if (pckReadType(ruleData) == pckTypeArray) + { + pckReadArrayBeginP(ruleData); + + while (!pckReadNullP(ruleData)) // {uncovered_branch - no options with partial allow range maps} + { + const unsigned int map = pckReadU32P(ruleData); + optionalRules->allowRangeMinIdx = pckReadU32P(ruleData); + optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData); + + if (map == optionalRules->matchValue) + { + optionalRules->allowRangeMatch = true; + break; + } + } + + match = optionalRules->allowRangeMatch; + } + else + { + optionalRules->allowRangeMinIdx = pckReadU32P(ruleData); + optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData); + } + optionalRules->allowRangeMin = cfgParseOptionValue(ruleOption->type, optionalRules->allowRangeMinIdx); optionalRules->allowRangeMax = cfgParseOptionValue(ruleOption->type, optionalRules->allowRangeMaxIdx); @@ -1098,38 +1190,30 @@ cfgParseOptionalRule( pckReadNext(ruleData); - switch (pckReadType(ruleData)) + if (pckReadType(ruleData) == pckTypeArray) { - case pckTypeBool: - optionalRules->defaultValue.boolean = pckReadBoolP(ruleData); - optionalRules->defaultRaw = optionalRules->defaultValue.boolean ? Y_STR : N_STR; - break; + pckReadArrayBeginP(ruleData); + match = false; - default: + while (!pckReadNullP(ruleData)) { - const unsigned int valueIdx = pckReadU32P(ruleData); + const unsigned int map = pckReadU32P(ruleData); - switch (ruleOption->type) + cfgParseOptionValuePack( + ruleData, ruleOption->type, &optionalRules->defaultValue, &optionalRules->defaultRaw); + + if (map == optionalRules->matchValue) { - case cfgOptTypeInteger: - case cfgOptTypeSize: - case cfgOptTypeTime: - optionalRules->defaultValue.integer = cfgParseOptionValue(ruleOption->type, valueIdx); - break; - - case cfgOptTypePath: - case cfgOptTypeString: - optionalRules->defaultValue.string = cfgParseOptionValueStr(ruleOption->type, valueIdx); - break; - - case cfgOptTypeStringId: - optionalRules->defaultValue.stringId = parseRuleValueStrId[valueIdx]; - break; + match = true; + break; } - - optionalRules->defaultRaw = cfgParseOptionValueStr(ruleOption->type, valueIdx); } } + else + { + cfgParseOptionValuePack( + ruleData, ruleOption->type, &optionalRules->defaultValue, &optionalRules->defaultRaw); + } } break; @@ -1160,7 +1244,7 @@ cfgParseOptionalRule( while (!result); } - FUNCTION_TEST_RETURN(BOOL, result); + FUNCTION_TEST_RETURN(BOOL, result && match); } /*********************************************************************************************************************************** @@ -1168,16 +1252,20 @@ Resolve an option dependency ***********************************************************************************************************************************/ typedef struct CfgParseOptionalFilterDependResult { - bool valid; - bool defaultExists; - bool defaultValue; + bool valid; // Is the dependency valid? + bool defaultExists; // Is there a default of the dependency is not valid? + ConfigOption dependId; // Option id for the dependency + ConfigOptionValueType defaultValue; // Default value if dependency is not valid + unsigned int matchValue; // Match value if the dependency is valid } CfgParseOptionalFilterDependResult; static CfgParseOptionalFilterDependResult -cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config, const unsigned int optionListIdx) +cfgParseOptionalFilterDepend( + PackRead *const filter, const ConfigOptionType optionType, const Config *const config, const unsigned int optionListIdx) { FUNCTION_TEST_BEGIN(); FUNCTION_TEST_PARAM(PACK_READ, filter); + FUNCTION_TEST_PARAM(ENUM, optionType); FUNCTION_TEST_PARAM_P(VOID, config); FUNCTION_TEST_PARAM(UINT, optionListIdx); FUNCTION_TEST_END(); @@ -1189,15 +1277,19 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config, if (pckReadType(filter) == pckTypeBool) { + pckReadBoolP(filter); + pckReadNext(filter); + result.defaultExists = true; - result.defaultValue = pckReadBoolP(filter); + + cfgParseOptionValuePack(filter, optionType, &result.defaultValue, NULL); } // Get the depend option value - const ConfigOption dependId = (ConfigOption)pckReadU32P(filter); - ASSERT(config->option[dependId].index != NULL); + result.dependId = (ConfigOption)pckReadU32P(filter); + ASSERT(config->option[result.dependId].index != NULL); const ConfigOptionValue *const dependValue = - &config->option[dependId].index[parseRuleOption[dependId].group ? optionListIdx : 0]; + &config->option[result.dependId].index[parseRuleOption[result.dependId].group ? optionListIdx : 0]; // Is the dependency resolved? if (dependValue->set) @@ -1207,7 +1299,7 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config, { do { - switch (cfgParseOptionDataType(dependId)) + switch (cfgParseOptionDataType(result.dependId)) { case cfgOptDataTypeBoolean: result.valid = pckReadBoolP(filter) == dependValue->value.boolean; @@ -1215,13 +1307,18 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config, default: { - ASSERT(cfgParseOptionDataType(dependId) == cfgOptDataTypeStringId); + ASSERT(cfgParseOptionDataType(result.dependId) == cfgOptDataTypeStringId); + result.matchValue = pckReadU32P(filter); - if (parseRuleValueStrId[pckReadU32P(filter)] == dependValue->value.stringId) + if (parseRuleValueStrId[result.matchValue] == dependValue->value.stringId) result.valid = true; + break; } } + + if (result.valid) + break; } while (pckReadNext(filter)); } @@ -2286,11 +2383,14 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha // Is the option valid? CfgParseOptionalRuleState optionalRules = {.defaultDynamicBin = config->bin}; CfgParseOptionalFilterDependResult dependResult = {.valid = true}; + const char *dependOptionName = NULL; if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeValid, config->command, optionId)) { PackRead *const filter = pckReadNewC(optionalRules.valid, optionalRules.validSize); - dependResult = cfgParseOptionalFilterDepend(filter, config, optionListIdx); + dependResult = cfgParseOptionalFilterDepend(filter, optionType, config, optionListIdx); + dependOptionName = cfgParseOptionKeyIdxName( + dependResult.dependId, parseRuleOption[dependResult.dependId].group ? optionKeyIdx : 0); // If depend not resolved and option value is set on the command-line then error. It is OK to have unresolved // options in the config file because they may be there for another command. For instance, spool-path is only @@ -2304,12 +2404,13 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha pckReadNext(filter); if (pckReadType(filter) == pckTypeBool) + { pckReadBoolP(filter); + pckReadConsume(filter); + } // Get depend option id and name const ConfigOption dependId = pckReadU32P(filter); - const String *dependOptionName = STR( - cfgParseOptionKeyIdxName(dependId, parseRuleOption[dependId].group ? optionKeyIdx : 0)); // If depend value is not set ASSERT(config->option[dependId].index != NULL); @@ -2318,7 +2419,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha { THROW_FMT( OptionInvalidError, "option '%s' not valid without option '%s'", - cfgParseOptionKeyIdxName(optionId, optionKeyIdx), strZ(dependOptionName)); + cfgParseOptionKeyIdxName(optionId, optionKeyIdx), dependOptionName); } // Build type dependent error data @@ -2329,7 +2430,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha case cfgOptTypeBoolean: { if (!pckReadBoolP(filter)) - dependOptionName = strNewFmt("no-%s", strZ(dependOptionName)); + dependOptionName = zNewFmt("no-%s", dependOptionName); break; } @@ -2359,9 +2460,12 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha THROW_FMT( OptionInvalidError, "option '%s' not valid without option '%s'%s", - cfgParseOptionKeyIdxName(optionId, optionKeyIdx), strZ(dependOptionName), strZ(errorValue)); + cfgParseOptionKeyIdxName(optionId, optionKeyIdx), dependOptionName, strZ(errorValue)); } + // Store the match value in case we need it to find the default, range, etc. + optionalRules.matchValue = dependResult.matchValue; + pckReadFree(filter); } @@ -2482,9 +2586,14 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha { THROW_FMT( OptionInvalidValueError, - "'%s' is out of range for '%s' option\n" + "'%s' is out of range for '%s' option%s\n" "HINT: allowed range is %s to %s inclusive", strZ(value), cfgParseOptionKeyIdxName(optionId, optionKeyIdx), + optionalRules.allowRangeMatch ? + zNewFmt( + " when '%s' option = '%s'", dependOptionName, + strZ(cfgParseOptionValueStr(cfgOptTypeStringId, optionalRules.matchValue))) : + "", strZ(cfgParseOptionValueStr(optionType, optionalRules.allowRangeMinIdx)), strZ(cfgParseOptionValueStr(optionType, optionalRules.allowRangeMaxIdx))); } @@ -2651,7 +2760,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha else if (dependResult.defaultExists) { configOptionValue->set = true; - configOptionValue->value.boolean = dependResult.defaultValue; + configOptionValue->value = dependResult.defaultValue; configOptionValue->defaultValue = optionalRules.defaultRaw; configOptionValue->display = optionalRules.defaultRaw; } diff --git a/test/code-count/file-type.yaml b/test/code-count/file-type.yaml index d4740e803..156d7ad6c 100644 --- a/test/code-count/file-type.yaml +++ b/test/code-count/file-type.yaml @@ -1315,10 +1315,6 @@ src/common/compress/helper.h: class: core type: c/h -src/common/compress/helper.intern.h: - class: core - type: c/h - src/common/compress/lz4/common.c: class: core type: c diff --git a/test/src/module/build/configTest.c b/test/src/module/build/configTest.c index 47403e839..75409d8c6 100644 --- a/test/src/module/build/configTest.c +++ b/test/src/module/build/configTest.c @@ -238,7 +238,7 @@ testRun(void) " option: config\n" " default: false\n"); - TEST_ERROR(bldCfgParse(storageTest), FormatError, "dependency default invalid for non-boolean option 'stanza'"); + TEST_ERROR(bldCfgParse(storageTest), FormatError, "dependency default invalid for non integer/boolean option 'stanza'"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("parse and render config"); @@ -321,6 +321,10 @@ testRun(void) " section: global\n" " type: string\n" " default: gz\n" + " allow-list:\n" + " - none\n" + " - bz2\n" + " - gz\n" " command:\n" " backup: {}\n" " archive-get:\n" @@ -334,9 +338,19 @@ testRun(void) " section: global\n" " type: integer\n" " required: false\n" - " allow-range: [-1, 9]\n" + " default:\n" + " - bz2: 9\n" + " - gz: 6\n" + " allow-range:\n" + " - bz2: [1, 9]\n" + " - gz: [-1, 9]\n" + " depend:\n" + " option: compress-type\n" + " default: 0\n" + " list:\n" + " - bz2\n" + " - gz\n" " command: compress-type\n" - " depend: compress-type\n" "\n" " compress-level-network:\n" " inherit: compress-level\n" @@ -449,6 +463,16 @@ testRun(void) " deprecate:\n" " backup-standby-old: {}\n" "\n" + " backup-copy:\n" + " section: global\n" + " type: boolean\n" + " default: false\n" + " depend: backup-standby\n" + " command:\n" + " backup: {}\n" + " command-role:\n" + " main: {}\n" + "\n" " pg-path:\n" " section: stanza\n" " group: pg\n" @@ -509,6 +533,7 @@ testRun(void) COMMENT_BLOCK_BEGIN "\n" "Option constants\n" COMMENT_BLOCK_END "\n" + "#define CFGOPT_BACKUP_COPY \"backup-copy\"\n" "#define CFGOPT_BACKUP_STANDBY \"backup-standby\"\n" "#define CFGOPT_BOOL_LIKE \"bool-like\"\n" "#define CFGOPT_BUFFER_SIZE \"buffer-size\"\n" @@ -525,7 +550,7 @@ testRun(void) "#define CFGOPT_STANZA \"stanza\"\n" "#define CFGOPT_TIMEOUT \"timeout\"\n" "\n" - "#define CFG_OPTION_TOTAL 17\n" + "#define CFG_OPTION_TOTAL 18\n" "\n" COMMENT_BLOCK_BEGIN "\n" "Option value constants\n" @@ -583,6 +608,7 @@ testRun(void) COMMENT_BLOCK_END "\n" "typedef enum\n" "{\n" + " cfgOptBackupCopy,\n" " cfgOptBackupStandby,\n" " cfgOptBoolLike,\n" " cfgOptBufferSize,\n" @@ -625,14 +651,17 @@ testRun(void) "{\n" " PARSE_RULE_STRPUB(\"-1\"),\n" " PARSE_RULE_STRPUB(\"/include\"),\n" + " PARSE_RULE_STRPUB(\"1\"),\n" " PARSE_RULE_STRPUB(\"100ms\"),\n" " PARSE_RULE_STRPUB(\"10s\"),\n" " PARSE_RULE_STRPUB(\"16KiB\"),\n" " PARSE_RULE_STRPUB(\"30m\"),\n" " PARSE_RULE_STRPUB(\"32KiB\"),\n" + " PARSE_RULE_STRPUB(\"6\"),\n" " PARSE_RULE_STRPUB(\"7w\"),\n" " PARSE_RULE_STRPUB(\"8KiB\"),\n" " PARSE_RULE_STRPUB(\"9\"),\n" + " PARSE_RULE_STRPUB(\"bz2\"),\n" " PARSE_RULE_STRPUB(\"check\"),\n" " PARSE_RULE_STRPUB(\"debug1\"),\n" " PARSE_RULE_STRPUB(\"error\"),\n" @@ -640,6 +669,7 @@ testRun(void) " PARSE_RULE_STRPUB(\"host1\"),\n" " PARSE_RULE_STRPUB(\"info\"),\n" " PARSE_RULE_STRPUB(\"n\"),\n" + " PARSE_RULE_STRPUB(\"none\"),\n" " PARSE_RULE_STRPUB(\"off\"),\n" " PARSE_RULE_STRPUB(\"warn\"),\n" " PARSE_RULE_STRPUB(\"y\"),\n" @@ -651,14 +681,17 @@ testRun(void) "{\n" " parseRuleValStrQT_DS_1_QT,\n" " parseRuleValStrQT_FS_include_QT,\n" + " parseRuleValStrQT_1_QT,\n" " parseRuleValStrQT_100ms_QT,\n" " parseRuleValStrQT_10s_QT,\n" " parseRuleValStrQT_16KiB_QT,\n" " parseRuleValStrQT_30m_QT,\n" " parseRuleValStrQT_32KiB_QT,\n" + " parseRuleValStrQT_6_QT,\n" " parseRuleValStrQT_7w_QT,\n" " parseRuleValStrQT_8KiB_QT,\n" " parseRuleValStrQT_9_QT,\n" + " parseRuleValStrQT_bz2_QT,\n" " parseRuleValStrQT_check_QT,\n" " parseRuleValStrQT_debug1_QT,\n" " parseRuleValStrQT_error_QT,\n" @@ -666,6 +699,7 @@ testRun(void) " parseRuleValStrQT_host1_QT,\n" " parseRuleValStrQT_info_QT,\n" " parseRuleValStrQT_n_QT,\n" + " parseRuleValStrQT_none_QT,\n" " parseRuleValStrQT_off_QT,\n" " parseRuleValStrQT_warn_QT,\n" " parseRuleValStrQT_y_QT,\n" @@ -725,18 +759,24 @@ testRun(void) "static const int parseRuleValueInt[] =\n" "{\n" " -1,\n" + " 1,\n" + " 6,\n" " 9,\n" "};\n" "\n" "static const uint8_t parseRuleValueIntStrMap[] =\n" "{\n" " parseRuleValStrQT_DS_1_QT,\n" + " parseRuleValStrQT_1_QT,\n" + " parseRuleValStrQT_6_QT,\n" " parseRuleValStrQT_9_QT,\n" "};\n" "\n" "typedef enum\n" "{\n" " parseRuleValIntDS_1,\n" + " parseRuleValInt1,\n" + " parseRuleValInt6,\n" " parseRuleValInt9,\n" "} ParseRuleValueInt;\n" "\n" @@ -897,6 +937,39 @@ testRun(void) "{\n" " PARSE_RULE_OPTION\n" " (\n" + " PARSE_RULE_OPTION_NAME(\"backup-copy\"),\n" + " PARSE_RULE_OPTION_TYPE(Boolean),\n" + " PARSE_RULE_OPTION_NEGATE(true),\n" + " PARSE_RULE_OPTION_RESET(true),\n" + " PARSE_RULE_OPTION_REQUIRED(true),\n" + " PARSE_RULE_OPTION_SECTION(Global),\n" + "\n" + " PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST\n" + " (\n" + " PARSE_RULE_OPTION_COMMAND(Backup)\n" + " ),\n" + "\n" + " PARSE_RULE_OPTIONAL\n" + " (\n" + " PARSE_RULE_OPTIONAL_GROUP\n" + " (\n" + " PARSE_RULE_OPTIONAL_DEPEND\n" + " (\n" + " PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_BOOL_TRUE),\n" + " PARSE_RULE_VAL_OPT(Online),\n" + " PARSE_RULE_VAL_BOOL_TRUE,\n" + " ),\n" + "\n" + " PARSE_RULE_OPTIONAL_DEFAULT\n" + " (\n" + " PARSE_RULE_VAL_BOOL_FALSE,\n" + " ),\n" + " ),\n" + " ),\n" + " ),\n" + COMMENT_SEPARATOR "\n" + " PARSE_RULE_OPTION\n" + " (\n" " PARSE_RULE_OPTION_NAME(\"backup-standby\"),\n" " PARSE_RULE_OPTION_TYPE(Boolean),\n" " PARSE_RULE_OPTION_BETA(true),\n" @@ -1094,17 +1167,61 @@ testRun(void) "\n" " PARSE_RULE_OPTIONAL_ALLOW_RANGE\n" " (\n" - " PARSE_RULE_VAL_INT(DS_1),\n" - " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(DS_1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " ),\n" + " ),\n" + "\n" + " PARSE_RULE_OPTIONAL_DEFAULT\n" + " (\n" + " PARSE_RULE_OPTIONAL_DEFAULT_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(6),\n" + " ),\n" " ),\n" " ),\n" "\n" " PARSE_RULE_OPTIONAL_GROUP\n" " (\n" + " PARSE_RULE_OPTIONAL_DEPEND\n" + " (\n" + " PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_INT(0)),\n" + " PARSE_RULE_VAL_OPT(CompressType),\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " ),\n" + "\n" " PARSE_RULE_OPTIONAL_ALLOW_RANGE\n" " (\n" - " PARSE_RULE_VAL_INT(DS_1),\n" - " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(DS_1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " ),\n" + " ),\n" + "\n" + " PARSE_RULE_OPTIONAL_DEFAULT\n" + " (\n" + " PARSE_RULE_OPTIONAL_DEFAULT_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(6),\n" + " ),\n" " ),\n" " ),\n" " ),\n" @@ -1158,8 +1275,15 @@ testRun(void) "\n" " PARSE_RULE_OPTIONAL_ALLOW_RANGE\n" " (\n" - " PARSE_RULE_VAL_INT(DS_1),\n" - " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(DS_1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " ),\n" " ),\n" " ),\n" "\n" @@ -1174,8 +1298,15 @@ testRun(void) "\n" " PARSE_RULE_OPTIONAL_ALLOW_RANGE\n" " (\n" - " PARSE_RULE_VAL_INT(DS_1),\n" - " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n" + " (\n" + " PARSE_RULE_VAL_STRID(Bz2),\n" + " PARSE_RULE_VAL_INT(1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " PARSE_RULE_VAL_STRID(Gz),\n" + " PARSE_RULE_VAL_INT(DS_1),\n" + " PARSE_RULE_VAL_INT(9),\n" + " ),\n" " ),\n" " ),\n" " ),\n" @@ -1233,6 +1364,13 @@ testRun(void) " PARSE_RULE_VAL_OPT(Config),\n" " ),\n" "\n" + " PARSE_RULE_OPTIONAL_ALLOW_LIST\n" + " (\n" + " PARSE_RULE_VAL_STR(none),\n" + " PARSE_RULE_VAL_STR(bz2),\n" + " PARSE_RULE_VAL_STR(gz),\n" + " ),\n" + "\n" " PARSE_RULE_OPTIONAL_DEFAULT\n" " (\n" " PARSE_RULE_VAL_STR(QT_gz_QT),\n" @@ -1241,6 +1379,13 @@ testRun(void) "\n" " PARSE_RULE_OPTIONAL_GROUP\n" " (\n" + " PARSE_RULE_OPTIONAL_ALLOW_LIST\n" + " (\n" + " PARSE_RULE_VAL_STR(none),\n" + " PARSE_RULE_VAL_STR(bz2),\n" + " PARSE_RULE_VAL_STR(gz),\n" + " ),\n" + "\n" " PARSE_RULE_OPTIONAL_DEFAULT\n" " (\n" " PARSE_RULE_VAL_STR(QT_gz_QT),\n" @@ -1768,9 +1913,10 @@ testRun(void) " cfgOptPgHost,\n" " cfgOptPgPath,\n" " cfgOptTimeout,\n" + " cfgOptBackupCopy,\n" " cfgOptBackupStandby,\n" - " cfgOptCompressLevel,\n" " cfgOptCompressType,\n" + " cfgOptCompressLevel,\n" " cfgOptCompressLevelNetwork,\n" "};\n"); } diff --git a/test/src/module/command/helpTest.c b/test/src/module/command/helpTest.c index 9a19c29e9..7478e244c 100644 --- a/test/src/module/command/helpTest.c +++ b/test/src/module/command/helpTest.c @@ -361,7 +361,6 @@ testRun(void) " --repo-storage-port repository storage port\n" " --repo-storage-tag repository storage tag(s)\n" " --repo-storage-upload-chunk-size repository storage upload chunk size\n" - " [default=4194304]\n" " --repo-storage-verify-tls repository storage certificate verify\n" " --repo-target-time target time for repository\n" " --repo-type type of storage used for the repository\n" @@ -656,12 +655,6 @@ testRun(void) "higher and because the chunk buffer must be allocated per process, larger\n" \ "process-max values will lead to more memory being consumed overall.\n" \ "\n" \ - "Default chunk sizes by repo type:\n" \ - "\n" \ - "* azure - 4MiB\n" \ - "* gcs - 4MiB\n" \ - "* s3 - 5MiB\n" \ - "\n" \ "Note that valid chunk sizes vary by storage type and by platform. For example,\n" \ "AWS S3 has a minimum chunk size of 5MiB but S3 clones may accept lower values.\n" \ "Terminology for chunk size varies by storage type, so when searching min/max\n" \ @@ -674,8 +667,8 @@ testRun(void) HELP_OPTION_CHUNK "\n" "default:\n" - " repo1: 5242880\n" - " repo2: 4194304\n", + " repo1: 5MiB\n" + " repo2: 4MiB\n", helpVersion); argList = strLstNew(); diff --git a/test/src/module/common/compressTest.c b/test/src/module/common/compressTest.c index 15e1425f1..f7b8646e4 100644 --- a/test/src/module/common/compressTest.c +++ b/test/src/module/common/compressTest.c @@ -233,13 +233,6 @@ testRun(void) TEST_ERROR(gzError(Z_VERSION_ERROR), FormatError, "zlib threw error: [-6] incompatible version"); TEST_ERROR(gzError(999), AssertError, "zlib threw error: [999] unknown error"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()"); - - TEST_RESULT_INT(compressLevelDefault(compressTypeGz), 6, "level default"); - TEST_RESULT_INT(compressLevelMin(compressTypeGz), -1, "level default"); - TEST_RESULT_INT(compressLevelMax(compressTypeGz), 9, "level default"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("gzDecompressToLog() and gzCompressToLog()"); @@ -282,13 +275,6 @@ testRun(void) TEST_ERROR(bz2Error(BZ_CONFIG_ERROR), AssertError, "bz2 error: [-9] config error"); TEST_ERROR(bz2Error(-999), AssertError, "bz2 error: [-999] unknown error"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()"); - - TEST_RESULT_INT(compressLevelDefault(compressTypeBz2), 9, "level default"); - TEST_RESULT_INT(compressLevelMin(compressTypeBz2), 1, "level default"); - TEST_RESULT_INT(compressLevelMax(compressTypeBz2), 9, "level default"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("bz2DecompressToLog() and bz2CompressToLog()"); @@ -322,13 +308,6 @@ testRun(void) TEST_RESULT_UINT(lz4Error(0), 0, "check success"); TEST_ERROR(lz4Error((size_t)-2), FormatError, "lz4 error: [-2] ERROR_maxBlockSize_invalid"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()"); - - TEST_RESULT_INT(compressLevelDefault(compressTypeLz4), 1, "level default"); - TEST_RESULT_INT(compressLevelMin(compressTypeLz4), -5, "level default"); - TEST_RESULT_INT(compressLevelMax(compressTypeLz4), 12, "level default"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("lz4DecompressToLog() and lz4CompressToLog()"); @@ -365,13 +344,6 @@ testRun(void) TEST_RESULT_UINT(zstError(0), 0, "check success"); TEST_ERROR(zstError((size_t)-12), FormatError, "zst error: [-12] Version not supported"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()"); - - TEST_RESULT_INT(compressLevelDefault(compressTypeZst), 3, "level default"); - TEST_RESULT_INT(compressLevelMin(compressTypeZst), -7, "level default"); - TEST_RESULT_INT(compressLevelMax(compressTypeZst), 22, "level default"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("zstDecompressToLog() and zstCompressToLog()"); diff --git a/test/src/module/config/loadTest.c b/test/src/module/config/loadTest.c index a9177f5f1..fd08b9081 100644 --- a/test/src/module/config/loadTest.c +++ b/test/src/module/config/loadTest.c @@ -501,39 +501,16 @@ testRun(void) TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 9, "compress-level=9"); TEST_RESULT_BOOL(cfgOptionValid(cfgOptCompress), false, "compress is not valid"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_TITLE("error on invalid compress level"); - - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "db"); - hrnCfgArgRawZ(argList, cfgOptCompressType, "gz"); - hrnCfgArgRawZ(argList, cfgOptCompressLevel, "-2"); - - TEST_ERROR( - hrnCfgLoadP(cfgCmdArchivePush, argList), OptionInvalidValueError, - "'-2' is out of range for 'compress-level' option when 'compress-type' option = 'gz'"); - - argList = strLstNew(); - hrnCfgArgRawZ(argList, cfgOptStanza, "db"); - hrnCfgArgRawZ(argList, cfgOptCompressType, "gz"); - hrnCfgArgRawZ(argList, cfgOptCompressLevel, "10"); - - TEST_ERROR( - hrnCfgLoadP(cfgCmdArchivePush, argList), OptionInvalidValueError, - "'10' is out of range for 'compress-level' option when 'compress-type' option = 'gz'"); - - // In practice level should not be used here but preserve the prior behavior in case something depends on it // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("do not check range when compress-type = none"); argList = strLstNew(); hrnCfgArgRawZ(argList, cfgOptStanza, "db"); hrnCfgArgRawZ(argList, cfgOptCompressType, "none"); - hrnCfgArgRawZ(argList, cfgOptCompressLevel, "3"); HRN_CFG_LOAD(cfgCmdArchivePush, argList); TEST_RESULT_UINT(cfgOptionStrId(cfgOptCompressType), CFGOPTVAL_COMPRESS_TYPE_NONE, "compress-type=none"); - TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 3, "compress-level=3"); + TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 0, "compress-level=0"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("warn when compress-type and compress both set"); diff --git a/test/src/module/config/parseTest.c b/test/src/module/config/parseTest.c index 3033ea73b..8e890e7df 100644 --- a/test/src/module/config/parseTest.c +++ b/test/src/module/config/parseTest.c @@ -1414,6 +1414,18 @@ testRun(void) "'65536' is out of range for 'process-max' option\n" "HINT: allowed range is 1 to 999 inclusive"); + argList = strLstNew(); + strLstAddZ(argList, TEST_BACKREST_EXE); + hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/db"); + hrnCfgArgRawZ(argList, cfgOptStanza, "db"); + hrnCfgArgRawZ(argList, cfgOptCompressType, "gz"); + hrnCfgArgRawZ(argList, cfgOptCompressLevel, "-2"); + strLstAddZ(argList, TEST_COMMAND_BACKUP); + TEST_ERROR( + cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), OptionInvalidValueError, + "'-2' is out of range for 'compress-level' option when 'compress-type' option = 'gz'\n" + "HINT: allowed range is -1 to 9 inclusive"); + // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("character value when integer expected"); @@ -1840,7 +1852,7 @@ testRun(void) BUFSTR( strNewFmt( "[global]\n" - "compress-level=3\n" + "compress-type=gz\n" "spool-path=/path/to/spool\n" "lock-path=/\n" "pg1-path=/not/path/to/db\n" @@ -1872,6 +1884,7 @@ testRun(void) "%s=ignore\n" "%s=/path/to/db2\n" "pg3-host=ignore\n" + "repo1-host=ssh-host\n" "recovery-option=c=d\n", cfgParseOptionKeyIdxName(cfgOptPgHost, 1), cfgParseOptionKeyIdxName(cfgOptPgPath, 1)))); @@ -1912,6 +1925,8 @@ testRun(void) TEST_RESULT_INT(cfgOptionSource(cfgOptPgPath), cfgSourceConfig, "pg1-path is source config"); TEST_RESULT_STR_Z( cfgOptionIdxStr(cfgOptPgPath, cfgOptionKeyToIdx(cfgOptPgPath, 256)), "/path/to/db256", "pg256-path is set"); + TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptRepoHost, 0), "ssh-host", "repo1-host is set"); + TEST_RESULT_BOOL(cfgOptionIdxTest(cfgOptRepoHostPort, 0), false, "repo1-host-port is not set for ssh"); TEST_RESULT_UINT(varUInt64(cfgOptionVar(cfgOptType)), STRID5("incr", 0x90dc90), "check type"); TEST_RESULT_STR_Z( cfgOptionDisplayVar(VARUINT64(STRID5("incr", 0x90dc90)), cfgOptTypeStringId), "incr", "check type display"); @@ -1935,8 +1950,8 @@ testRun(void) TEST_RESULT_INT(cfgOptionSource(cfgOptRepoHardlink), cfgSourceConfig, "repo-hardlink is source config"); TEST_RESULT_UINT(cfgOptionUInt(cfgOptRepoRetentionFull), 55, "repo-retention-full is set"); TEST_RESULT_INT(varInt64(cfgOptionVar(cfgOptRepoRetentionFull)), 55, "repo-retention-full as variant"); - TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 3, "compress-level is set"); - TEST_RESULT_INT(cfgOptionSource(cfgOptCompressLevel), cfgSourceConfig, "compress-level is source config"); + TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 6, "compress-level is set"); + TEST_RESULT_INT(cfgOptionSource(cfgOptCompressLevel), cfgSourceDefault, "compress-level is source config"); TEST_RESULT_UINT(cfgOptionStrId(cfgOptBackupStandby), CFGOPTVAL_BACKUP_STANDBY_N, "backup-standby not is set"); TEST_RESULT_INT(cfgOptionSource(cfgOptBackupStandby), cfgSourceDefault, "backup-standby is source default"); TEST_RESULT_BOOL(cfgOptionIdxReset(cfgOptBackupStandby, 0), true, "backup-standby was reset"); @@ -2212,6 +2227,19 @@ testRun(void) TEST_RESULT_VOID(cfgOptionIdxSet(cfgOptType, 0, cfgSourceParam, VARSTRDEF("standby")), "set type"); TEST_RESULT_UINT(cfgOptionIdxStrId(cfgOptType, 0), STRID5("standby", 0x6444706930), "check type"); + // ------------------------------------------------------------------------------------------------------------------------- + TEST_TITLE("integer default when dependency invalid"); + { + argList = strLstNew(); + hrnCfgArgRawZ(argList, cfgOptStanza, "test"); + hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 1, "/pg1"); + hrnCfgEnvKeyRawZ(cfgOptRepoRetentionFull, 1, "1"); + hrnCfgEnvRawZ(cfgOptCompressType, "none"); + HRN_CFG_LOAD(cfgCmdBackup, argList); + + TEST_RESULT_UINT(cfgOptionUInt(cfgOptCompressLevel), 0, "compress-level is 0"); + } + // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("stanza options should not be loaded for commands that don't take a stanza"); diff --git a/test/src/module/doc/buildTest.c b/test/src/module/doc/buildTest.c index 1c7ae4fd4..0bebba4a6 100644 --- a/test/src/module/doc/buildTest.c +++ b/test/src/module/doc/buildTest.c @@ -77,6 +77,14 @@ testRun(void) " default: 1024\n" " allow-list: [512, 1024, 2048, 4096]\n" "\n" + " buffer-size-range:\n" + " section: global\n" + " type: integer\n" + " default: 1024\n" + " allow-range: [512, 1024]\n" + " command:\n" + " backup: {}\n" + "\n" " cmd:\n" " section: global\n" " type: string\n" @@ -97,11 +105,34 @@ testRun(void) " secure: true\n" " default: false\n" "\n" + " compress-type:\n" + " section: global\n" + " type: string-id\n" + " default: gz\n" + " allow-list:\n" + " - none\n" + " - bz2\n" + " - gz\n" + " command:\n" + " backup: {}\n" + " command-role: {}\n" + "\n" " repo-compress-level:\n" " group: repo\n" " type: integer\n" " default: 9\n" - " allow-range: [0, 9]\n" + " default:\n" + " - bz2: 9\n" + " - gz: 6\n" + " allow-range:\n" + " - bz2: [1, 9]\n" + " - gz: [-1, 9]\n" + " depend:\n" + " option: compress-type\n" + " default: 0\n" + " list:\n" + " - bz2\n" + " - gz\n" " command:\n" " backup: {}\n" " deprecate:\n" @@ -159,6 +190,11 @@ testRun(void) " 256KiB\n" " \n" "\n" + " \n" + " Compress type option command backup summary.\n" + "

Compress type option command backup description.

\n" + "
\n" + "\n" " \n" " Internal option summary.\n" "

Internal option description

\n" @@ -197,6 +233,12 @@ testRun(void) "

Backup command description.

\n" "\n" " \n" + " \n" + "\n" "