1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-11-08 03:22:25 +03:00

Add stack trace macros to all functions.

Low-level functions only include stack trace in test builds while higher-level functions ship with stack trace built-in. Stack traces include all parameters passed to the function but production builds only create the parameter list when the log level is set high enough, i.e. debug or trace depending on the function.
This commit is contained in:
David Steele
2018-05-18 11:57:32 -04:00
parent abb9651f4c
commit 52bc073234
141 changed files with 6489 additions and 1179 deletions

View File

@@ -25,6 +25,10 @@
</release-improvement-list> </release-improvement-list>
<release-development-list> <release-development-list>
<release-item>
<p>Add stack trace macros to all functions. Low-level functions only include stack trace in test builds while higher-level functions ship with stack trace built-in. Stack traces include all parameters passed to the function but production builds only create the parameter list when the log level is set high enough, i.e. <id>debug</id> or <id>trace</id> depending on the function.</p>
</release-item>
<release-item> <release-item>
<p>Build <path>libc</path> using links rather than referencing the C files in <path>src</path> directly. The C library builds with different options which should not be reused for the C binary or vice versa.</p> <p>Build <path>libc</path> using links rather than referencing the C files in <path>src</path> directly. The C library builds with different options which should not be reused for the C binary or vice versa.</p>
</release-item> </release-item>

View File

@@ -15,7 +15,10 @@ use ExtUtils::MakeMaker;
use File::Basename qw(dirname); use File::Basename qw(dirname);
use lib dirname($0) . '/lib'; use lib dirname($0) . '/lib';
use lib dirname($0) . '/build/lib';
use pgBackRest::LibCAuto; use pgBackRest::LibCAuto;
use pgBackRestLibC::BuildParam;
#################################################################################################################################### ####################################################################################################################################
# Storage object to use for all file operations # Storage object to use for all file operations
@@ -77,6 +80,7 @@ my @stryCFile =
'cipher/cipher.c', 'cipher/cipher.c',
'cipher/random.c', 'cipher/random.c',
'command/command.c', 'command/command.c',
'common/debug.c',
'common/encode.c', 'common/encode.c',
'common/encode/base64.c', 'common/encode/base64.c',
'common/error.c', 'common/error.c',
@@ -86,7 +90,9 @@ my @stryCFile =
'common/log.c', 'common/log.c',
'common/memContext.c', 'common/memContext.c',
'common/regExp.c', 'common/regExp.c',
'common/stackTrace.c',
'common/time.c', 'common/time.c',
'common/type/convert.c',
'common/type/buffer.c', 'common/type/buffer.c',
'common/type/keyValue.c', 'common/type/keyValue.c',
'common/type/list.c', 'common/type/list.c',
@@ -142,15 +148,7 @@ WriteMakefile
VERSION_FROM => 'lib/' . BACKREST_NAME . '/LibC.pm', VERSION_FROM => 'lib/' . BACKREST_NAME . '/LibC.pm',
AUTHOR => 'David Steele <david@pgbackrest.org>', AUTHOR => 'David Steele <david@pgbackrest.org>',
CCFLAGS => join(' ', qw( CCFLAGS => join(' ', buildParamCCAll()),
-Wfatal-errors -Wall -Wextra -Wwrite-strings -Wno-clobbered -Wno-missing-field-initializers
-o $@
-std=c99
-D_FILE_OFFSET_BITS=64
-funroll-loops
-ftree-vectorize
$(CFLAGS)
)),
INC => join(' ', qw( INC => join(' ', qw(
-I. -I.

View File

@@ -0,0 +1,46 @@
####################################################################################################################################
# Parameters used by LibC builds
####################################################################################################################################
package pgBackRestLibC::BuildParam;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Exporter qw(import);
our @EXPORT = qw();
####################################################################################################################################
# All CC params used for a debug build
####################################################################################################################################
sub buildParamCCDebug
{
return qw(
-Wfatal-errors -Wall -Wextra -Wwrite-strings -Wno-clobbered -Wno-missing-field-initializers
-o $@
-std=c99
-D_FILE_OFFSET_BITS=64
$(CFLAGS));
}
push @EXPORT, qw(buildParamCCDebug);
####################################################################################################################################
# All CC params used for a production build
####################################################################################################################################
sub buildParamCCAll
{
my @stryParams = buildParamCCDebug;
push(@stryParams, qw(
-DNDEBUG
-funroll-loops
-ftree-vectorize));
return @stryParams;
}
push @EXPORT, qw(buildParamCCAll);
1;

View File

@@ -59,17 +59,20 @@ SRCS = \
command/archive/push/push.c \ command/archive/push/push.c \
command/help/help.c \ command/help/help.c \
command/command.c \ command/command.c \
common/fork.c \ common/debug.c \
common/error.c \ common/error.c \
common/exit.c \ common/exit.c \
common/fork.c \
common/io/handle.c \ common/io/handle.c \
common/ini.c \ common/ini.c \
common/lock.c \ common/lock.c \
common/log.c \ common/log.c \
common/memContext.c \ common/memContext.c \
common/regExp.c \ common/regExp.c \
common/stackTrace.c \
common/time.c \ common/time.c \
common/type/buffer.c \ common/type/buffer.c \
common/type/convert.c \
common/type/keyValue.c \ common/type/keyValue.c \
common/type/list.c \ common/type/list.c \
common/type/string.c \ common/type/string.c \

View File

@@ -6,6 +6,7 @@ Block Cipher
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/err.h> #include <openssl/err.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "cipher/block.h" #include "cipher/block.h"
#include "cipher/random.h" #include "cipher/random.h"
@@ -45,6 +46,18 @@ New block encrypt/decrypt object
CipherBlock * CipherBlock *
cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName) cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pass, size_t passSize, const char *digestName)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, mode);
FUNCTION_DEBUG_PARAM(STRINGZ, cipherName);
FUNCTION_DEBUG_PARAM(UCHARP, pass);
FUNCTION_DEBUG_PARAM(SIZE, passSize);
FUNCTION_DEBUG_PARAM(STRINGZ, digestName);
FUNCTION_DEBUG_ASSERT(cipherName != NULL);
FUNCTION_DEBUG_ASSERT(pass != NULL);
FUNCTION_DEBUG_ASSERT(passSize > 0);
FUNCTION_DEBUG_END();
// Only need to init once. // Only need to init once.
if (!cipherIsInit()) if (!cipherIsInit())
cipherInit(); cipherInit();
@@ -90,7 +103,7 @@ cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pas
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(CIPHER_BLOCK, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -99,6 +112,13 @@ Determine how large the destination buffer should be
size_t size_t
cipherBlockProcessSize(CipherBlock *this, size_t sourceSize) cipherBlockProcessSize(CipherBlock *this, size_t sourceSize)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(CIPHER_BLOCK, this);
FUNCTION_DEBUG_PARAM(SIZE, sourceSize);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Destination size is source size plus one extra block // Destination size is source size plus one extra block
size_t destinationSize = sourceSize + EVP_MAX_BLOCK_LENGTH; size_t destinationSize = sourceSize + EVP_MAX_BLOCK_LENGTH;
@@ -106,7 +126,7 @@ cipherBlockProcessSize(CipherBlock *this, size_t sourceSize)
if (this->mode == cipherModeEncrypt && !this->saltDone) if (this->mode == cipherModeEncrypt && !this->saltDone)
destinationSize += CIPHER_BLOCK_MAGIC_SIZE + PKCS5_SALT_LEN; destinationSize += CIPHER_BLOCK_MAGIC_SIZE + PKCS5_SALT_LEN;
return destinationSize; FUNCTION_DEBUG_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -115,6 +135,17 @@ Encrypt/decrypt data
size_t size_t
cipherBlockProcess(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination) cipherBlockProcess(CipherBlock *this, const unsigned char *source, size_t sourceSize, unsigned char *destination)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(CIPHER_BLOCK, this);
FUNCTION_DEBUG_PARAM(UCHARP, source);
FUNCTION_DEBUG_PARAM(SIZE, sourceSize);
FUNCTION_DEBUG_PARAM(UCHARP, destination);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(source != NULL);
FUNCTION_DEBUG_ASSERT(destination != NULL);
FUNCTION_DEBUG_END();
// Actual destination size // Actual destination size
size_t destinationSize = 0; size_t destinationSize = 0;
@@ -212,7 +243,7 @@ cipherBlockProcess(CipherBlock *this, const unsigned char *source, size_t source
} }
// Return actual destination size // Return actual destination size
return destinationSize; FUNCTION_DEBUG_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -221,6 +252,14 @@ Flush the remaining data
size_t size_t
cipherBlockFlush(CipherBlock *this, unsigned char *destination) cipherBlockFlush(CipherBlock *this, unsigned char *destination)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(CIPHER_BLOCK, this);
FUNCTION_DEBUG_PARAM(UCHARP, destination);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(destination != NULL);
FUNCTION_DEBUG_END();
// Actual destination size // Actual destination size
size_t destinationSize = 0; size_t destinationSize = 0;
@@ -233,7 +272,7 @@ cipherBlockFlush(CipherBlock *this, unsigned char *destination)
THROW(CipherError, "unable to flush"); THROW(CipherError, "unable to flush");
// Return actual destination size // Return actual destination size
return destinationSize; FUNCTION_DEBUG_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -242,10 +281,18 @@ Free memory
void void
cipherBlockFree(CipherBlock *this) cipherBlockFree(CipherBlock *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(CIPHER_BLOCK, this);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Free cipher context // Free cipher context
if (this->cipherContext) if (this->cipherContext)
EVP_CIPHER_CTX_cleanup(this->cipherContext); EVP_CIPHER_CTX_cleanup(this->cipherContext);
// Free mem context // Free mem context
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -21,4 +21,12 @@ size_t cipherBlockProcess(CipherBlock *this, const unsigned char *source, size_t
size_t cipherBlockFlush(CipherBlock *this, unsigned char *destination); size_t cipherBlockFlush(CipherBlock *this, unsigned char *destination);
void cipherBlockFree(CipherBlock *this); void cipherBlockFree(CipherBlock *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_CIPHER_BLOCK_TYPE \
CipherBlock *
#define FUNCTION_DEBUG_CIPHER_BLOCK_FORMAT(value, buffer, bufferSize) \
objToLog(value, "CipherBlock", buffer, bufferSize)
#endif #endif

View File

@@ -6,6 +6,7 @@ Cipher General Init and Free
#include <openssl/err.h> #include <openssl/err.h>
#include "cipher/cipher.h" #include "cipher/cipher.h"
#include "common/debug.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Flag to indicate if OpenSSL has already been initialized Flag to indicate if OpenSSL has already been initialized
@@ -18,6 +19,8 @@ Initialize ciphers
void void
cipherInit() cipherInit()
{ {
FUNCTION_DEBUG_VOID(logLevelTrace);
if (!cipherInitDone) if (!cipherInitDone)
{ {
ERR_load_crypto_strings(); ERR_load_crypto_strings();
@@ -25,6 +28,8 @@ cipherInit()
cipherInitDone = true; cipherInitDone = true;
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -33,23 +38,6 @@ Have the ciphers been initialized?
bool bool
cipherIsInit() cipherIsInit()
{ {
return cipherInitDone; FUNCTION_TEST_VOID();
} FUNCTION_TEST_RESULT(BOOL, cipherInitDone);
/***********************************************************************************************************************************
Free ciphers
***********************************************************************************************************************************/
void
cipherFree()
{
if (cipherInitDone)
{
FIPS_mode_set(0);
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_thread_state(NULL);
ERR_free_strings();
cipherInitDone = false;
}
} }

View File

@@ -20,6 +20,5 @@ Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void cipherInit(); void cipherInit();
bool cipherIsInit(); bool cipherIsInit();
void cipherFree();
#endif #endif

View File

@@ -4,6 +4,8 @@ Cipher
#include <openssl/rand.h> #include <openssl/rand.h>
#include "cipher/random.h" #include "cipher/random.h"
#include "common/debug.h"
#include "common/error.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Generate random bytes Generate random bytes
@@ -11,5 +13,15 @@ Generate random bytes
void void
randomBytes(unsigned char *buffer, size_t size) randomBytes(unsigned char *buffer, size_t size)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(UCHARP, buffer);
FUNCTION_DEBUG_PARAM(SIZE, size);
FUNCTION_DEBUG_ASSERT(buffer != NULL);
FUNCTION_DEBUG_ASSERT(size > 0);
FUNCTION_DEBUG_END();
RAND_bytes(buffer, (int)size); RAND_bytes(buffer, (int)size);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -7,6 +7,7 @@ Archive Push Command
#include "command/archive/common.h" #include "command/archive/common.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/wait.h" #include "common/wait.h"
@@ -19,6 +20,12 @@ Check for ok/error status files in the spool in/out directory
bool bool
archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confessOnError) archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confessOnError)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(ENUM, archiveMode);
FUNCTION_DEBUG_PARAM(STRING, walSegment);
FUNCTION_DEBUG_PARAM(BOOL, confessOnError);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -98,7 +105,7 @@ archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confe
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -107,10 +114,16 @@ Get the next WAL segment given a WAL segment and WAL segment size
String * String *
walSegmentNext(const String *walSegment, size_t walSegmentSize, uint pgVersion) walSegmentNext(const String *walSegment, size_t walSegmentSize, uint pgVersion)
{ {
ASSERT_DEBUG(walSegment != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
ASSERT_DEBUG(strSize(walSegment) == 24); FUNCTION_DEBUG_PARAM(STRING, walSegment);
ASSERT_DEBUG(UINT32_MAX % walSegmentSize == walSegmentSize - 1); FUNCTION_DEBUG_PARAM(SIZE, walSegmentSize);
ASSERT_DEBUG(pgVersion >= PG_VERSION_11 || walSegmentSize == 16 * 1024 * 1024); FUNCTION_DEBUG_PARAM(UINT, pgVersion);
FUNCTION_DEBUG_ASSERT(walSegment != NULL);
FUNCTION_DEBUG_ASSERT(strSize(walSegment) == 24);
FUNCTION_DEBUG_ASSERT(UINT32_MAX % walSegmentSize == walSegmentSize - 1);
FUNCTION_DEBUG_ASSERT(pgVersion >= PG_VERSION_11 || walSegmentSize == 16 * 1024 * 1024);
FUNCTION_DEBUG_END();
// Extract WAL parts // Extract WAL parts
uint32_t timeline = 0; uint32_t timeline = 0;
@@ -141,7 +154,7 @@ walSegmentNext(const String *walSegment, size_t walSegmentSize, uint pgVersion)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return strNewFmt("%08X%08X%08X", timeline, major, minor); FUNCTION_DEBUG_RESULT(STRING, strNewFmt("%08X%08X%08X", timeline, major, minor));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -150,7 +163,13 @@ Build a list of WAL segments based on a beginning WAL and number of WAL in the r
StringList * StringList *
walSegmentRange(const String *walSegmentBegin, size_t walSegmentSize, uint pgVersion, uint range) walSegmentRange(const String *walSegmentBegin, size_t walSegmentSize, uint pgVersion, uint range)
{ {
ASSERT_DEBUG(range > 0); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, walSegmentBegin);
FUNCTION_DEBUG_PARAM(SIZE, walSegmentSize);
FUNCTION_DEBUG_PARAM(UINT, pgVersion);
FUNCTION_DEBUG_ASSERT(range > 0);
FUNCTION_DEBUG_END();
StringList *result = NULL; StringList *result = NULL;
@@ -177,5 +196,5 @@ walSegmentRange(const String *walSegmentBegin, size_t walSegmentSize, uint pgVer
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STRING_LIST, result);
} }

View File

@@ -6,6 +6,8 @@ Archive Get Command
#include "command/archive/common.h" #include "command/archive/common.h"
#include "command/command.h" #include "command/command.h"
#include "common/assert.h"
#include "common/debug.h"
#include "common/fork.h" #include "common/fork.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
@@ -23,6 +25,16 @@ Clean the queue and prepare a list of WAL segments that the async process should
static StringList * static StringList *
queueNeed(const String *walSegment, bool found, size_t queueSize, size_t walSegmentSize, uint pgVersion) queueNeed(const String *walSegment, bool found, size_t queueSize, size_t walSegmentSize, uint pgVersion)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, walSegment);
FUNCTION_DEBUG_PARAM(BOOL, found);
FUNCTION_DEBUG_PARAM(SIZE, queueSize);
FUNCTION_DEBUG_PARAM(SIZE, walSegmentSize);
FUNCTION_DEBUG_PARAM(UINT, pgVersion);
FUNCTION_DEBUG_ASSERT(walSegment != NULL);
FUNCTION_DEBUG_END();
StringList *result = strLstNew(); StringList *result = strLstNew();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -76,7 +88,7 @@ queueNeed(const String *walSegment, bool found, size_t queueSize, size_t walSegm
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -85,6 +97,8 @@ Push a WAL segment to the repository
int int
cmdArchiveGet() cmdArchiveGet()
{ {
FUNCTION_DEBUG_VOID(logLevelDebug);
int result = 1; int result = 1;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -98,9 +112,9 @@ cmdArchiveGet()
THROW(ParamRequiredError, "WAL segment to get required"); THROW(ParamRequiredError, "WAL segment to get required");
if (strLstSize(commandParam) == 1) if (strLstSize(commandParam) == 1)
THROW(ParamRequiredError, "Path to copy WAL segment required"); THROW(ParamRequiredError, "path to copy WAL segment required");
THROW(ParamRequiredError, "extra parameters found"); THROW(ParamInvalidError, "extra parameters found");
} }
// Get the segment name // Get the segment name
@@ -270,5 +284,5 @@ cmdArchiveGet()
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(INT, result);
} }

View File

@@ -5,6 +5,7 @@ Archive Push Command
#include "command/archive/common.h" #include "command/archive/common.h"
#include "command/command.h" #include "command/command.h"
#include "common/debug.h"
#include "common/fork.h" #include "common/fork.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
@@ -20,6 +21,8 @@ Push a WAL segment to the repository
void void
cmdArchivePush() cmdArchivePush()
{ {
FUNCTION_DEBUG_VOID(logLevelDebug);
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
// Make sure there is a parameter to retrieve the WAL segment from // Make sure there is a parameter to retrieve the WAL segment from
@@ -123,4 +126,6 @@ cmdArchivePush()
THROW(AssertError, "archive-push in C does not support synchronous mode"); THROW(AssertError, "archive-push in C does not support synchronous mode");
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -4,25 +4,23 @@ Common Command Routines
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/log.h" #include "common/log.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
#include "version.h" #include "version.h"
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
// The command must be set
#define ASSERT_DEBUG_COMMAND_SET() \
ASSERT_DEBUG(cfgCommand() != cfgCmdNone)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Begin the command Begin the command
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void void
cmdBegin(bool logOption) cmdBegin(bool logOption)
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(BOOL, logOption);
FUNCTION_DEBUG_ASSERT(cfgCommand() != cfgCmdNone);
FUNCTION_DEBUG_END();
// This is fairly expensive log message to generate so skip it if it won't be output // This is fairly expensive log message to generate so skip it if it won't be output
if (logWill(cfgLogLevelDefault())) if (logWill(cfgLogLevelDefault()))
@@ -134,10 +132,12 @@ cmdBegin(bool logOption)
} }
} }
LOG_ANY(cfgLogLevelDefault(), 0, strPtr(info)); LOG(cfgLogLevelDefault(), 0, strPtr(info));
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -146,8 +146,13 @@ End the command
void void
cmdEnd(int code, const String *errorMessage) cmdEnd(int code, const String *errorMessage)
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_DEBUG_BEGIN(logLevelTrace);
ASSERT_DEBUG(code == 0 || errorMessage != NULL); FUNCTION_DEBUG_PARAM(INT, code);
FUNCTION_DEBUG_PARAM(STRING, errorMessage);
FUNCTION_DEBUG_ASSERT(cfgCommand() != cfgCmdNone);
FUNCTION_DEBUG_ASSERT(code == 0 || errorMessage != NULL);
FUNCTION_DEBUG_END();
// Skip this log message if it won't be output. It's not too expensive but since we skipped cmdBegin(), may as well. // Skip this log message if it won't be output. It's not too expensive but since we skipped cmdBegin(), may as well.
if (logWill(cfgLogLevelDefault())) if (logWill(cfgLogLevelDefault()))
@@ -162,8 +167,10 @@ cmdEnd(int code, const String *errorMessage)
else else
strCat(info, strPtr(errorMessage)); strCat(info, strPtr(errorMessage));
LOG_ANY(cfgLogLevelDefault(), 0, strPtr(info)); LOG(cfgLogLevelDefault(), 0, strPtr(info));
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
} }
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -5,6 +5,8 @@ Help Command
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "common/assert.h"
#include "common/debug.h"
#include "common/io/handle.h" #include "common/io/handle.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
@@ -22,6 +24,16 @@ Helper function for helpRender() to make output look good on a console
static String * static String *
helpRenderText(const String *text, size_t indent, bool indentFirst, size_t length) helpRenderText(const String *text, size_t indent, bool indentFirst, size_t length)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, text);
FUNCTION_DEBUG_PARAM(SIZE, indent);
FUNCTION_DEBUG_PARAM(BOOL, indentFirst);
FUNCTION_DEBUG_PARAM(SIZE, length);
FUNCTION_DEBUG_ASSERT(text != NULL);
FUNCTION_DEBUG_ASSERT(length > 0);
FUNCTION_DEBUG_END();
String *result = strNew(""); String *result = strNew("");
// Split the text into paragraphs // Split the text into paragraphs
@@ -54,7 +66,7 @@ helpRenderText(const String *text, size_t indent, bool indentFirst, size_t lengt
} }
} }
return result; FUNCTION_DEBUG_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -63,6 +75,10 @@ Helper function for helpRender() to output values as strings
static String * static String *
helpRenderValue(const Variant *value) helpRenderValue(const Variant *value)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(VARIANT, value);
FUNCTION_DEBUG_END();
String *result = NULL; String *result = NULL;
if (value != NULL) if (value != NULL)
@@ -109,7 +125,7 @@ helpRenderValue(const Variant *value)
result = varStrForce(value); result = varStrForce(value);
} }
return result; FUNCTION_DEBUG_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -118,6 +134,8 @@ Render help to a string
static String * static String *
helpRender() helpRender()
{ {
FUNCTION_DEBUG_VOID(logLevelDebug);
String *result = strNew(PGBACKREST_NAME " " PGBACKREST_VERSION); String *result = strNew(PGBACKREST_NAME " " PGBACKREST_VERSION);
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -358,7 +376,7 @@ helpRender()
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -367,9 +385,13 @@ Render help and output to stdout
void void
cmdHelp() cmdHelp()
{ {
FUNCTION_DEBUG_VOID(logLevelDebug);
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
ioHandleWriteOneStr(STDOUT_FILENO, helpRender()); ioHandleWriteOneStr(STDOUT_FILENO, helpRender());
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -10,10 +10,12 @@ Assert Routines
For very important asserts that are shipped with the production code For very important asserts that are shipped with the production code
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define ASSERT(condition) \ #define ASSERT(condition) \
do \
{ \ { \
if (!(condition)) \ if (!(condition)) \
THROW_FMT(AssertError, "assertion '%s' failed", #condition); \ THROW_FMT(AssertError, "assertion '%s' failed", #condition); \
} } \
while (0)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Used for assertions that should only be run when debugging. Ideal for conditions that need to be tested during development but Used for assertions that should only be run when debugging. Ideal for conditions that need to be tested during development but
@@ -21,10 +23,12 @@ be too expensive to ship with the production code.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#ifndef NDEBUG #ifndef NDEBUG
#define ASSERT_DEBUG(condition) \ #define ASSERT_DEBUG(condition) \
do \
{ \ { \
if (!(condition)) \ if (!(condition)) \
THROW_FMT(AssertError, "debug assertion '%s' failed", #condition); \ THROW_FMT(AssertError, "debug assertion '%s' failed", #condition); \
} } \
while (0)
#else #else
#define ASSERT_DEBUG(condition) #define ASSERT_DEBUG(condition)
#endif #endif

47
src/common/debug.c Normal file
View File

@@ -0,0 +1,47 @@
/***********************************************************************************************************************************
Debug Routines
***********************************************************************************************************************************/
#include <stdio.h>
#include "common/debug.h"
/***********************************************************************************************************************************
Convert object to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
objToLog(const void *object, const char *objectName, char *buffer, size_t bufferSize)
{
size_t result = 0;
if (object == NULL)
result = (size_t)snprintf(buffer, bufferSize, "null");
else
result = (size_t)snprintf(buffer, bufferSize, "{%s}", objectName);
return result;
}
/***********************************************************************************************************************************
Convert pointer to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
ptrToLog(const void *pointer, const char *pointerName, char *buffer, size_t bufferSize)
{
size_t result = 0;
if (pointer == NULL)
result = (size_t)snprintf(buffer, bufferSize, "null");
else
result = (size_t)snprintf(buffer, bufferSize, "(%s)", pointerName);
return result;
}
/***********************************************************************************************************************************
Convert zero-terminated string for logging
***********************************************************************************************************************************/
size_t
strzToLog(const char *string, char *buffer, size_t bufferSize)
{
return (size_t)snprintf(buffer, bufferSize, string == NULL ? "%s" : "\"%s\"", string == NULL ? "null" : string);
}

View File

@@ -4,6 +4,9 @@ Debug Routines
#ifndef COMMON_DEBUG_H #ifndef COMMON_DEBUG_H
#define COMMON_DEBUG_H #define COMMON_DEBUG_H
#include "common/stackTrace.h"
#include "common/type/convert.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
NDEBUG indicates to C library routines that debugging is off -- set a more readable flag to use when debugging is on NDEBUG indicates to C library routines that debugging is off -- set a more readable flag to use when debugging is on
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -21,4 +24,294 @@ Extern variables that are needed for unit testing
static static
#endif #endif
/***********************************************************************************************************************************
Base function debugging macros
In debug mode parameters will always be recorded in the stack trace while in production mode they will only be recorded when the log
level is set to debug or trace.
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_LEVEL() \
FUNCTION_DEBUG_logLevel
#ifdef DEBUG
#define FUNCTION_DEBUG_BEGIN_BASE(logLevel) \
LogLevel FUNCTION_DEBUG_LEVEL() = STACK_TRACE_PUSH(logLevel); \
\
{ \
stackTraceParamLog();
#define FUNCTION_DEBUG_END_BASE() \
LOG_WILL(FUNCTION_DEBUG_LEVEL(), 0, "(%s)", stackTraceParam()); \
}
#define FUNCTION_DEBUG_PARAM_BASE_BEGIN() \
stackTraceTestStop() \
#define FUNCTION_DEBUG_PARAM_BASE_END() \
stackTraceTestStart()
#else
#define FUNCTION_DEBUG_BEGIN_BASE(logLevel) \
LogLevel FUNCTION_DEBUG_LEVEL() = STACK_TRACE_PUSH(logLevel); \
\
if (logWill(FUNCTION_DEBUG_LEVEL())) \
{ \
stackTraceParamLog()
#define FUNCTION_DEBUG_END_BASE() \
LOG(FUNCTION_DEBUG_LEVEL(), 0, "(%s)", stackTraceParam()); \
}
#define FUNCTION_DEBUG_PARAM_BASE_BEGIN()
#define FUNCTION_DEBUG_PARAM_BASE_END()
#endif
/***********************************************************************************************************************************
General purpose function debugging macros
FUNCTION_DEBUG_VOID() is provided as a shortcut for functions that have no parameters.
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_BEGIN(logLevel) \
FUNCTION_DEBUG_BEGIN_BASE(logLevel)
#define FUNCTION_DEBUG_END() \
FUNCTION_DEBUG_END_BASE()
#define FUNCTION_DEBUG_VOID(logLevel) \
FUNCTION_DEBUG_BEGIN_BASE(logLevel); \
FUNCTION_DEBUG_END_BASE()
#define FUNCTION_DEBUG_PARAM(typeMacroPrefix, param) \
FUNCTION_DEBUG_PARAM_BASE_BEGIN(); \
stackTraceParamAdd(FUNCTION_DEBUG_##typeMacroPrefix##_FORMAT(param, stackTraceParamBuffer(#param), STACK_TRACE_PARAM_MAX)); \
FUNCTION_DEBUG_PARAM_BASE_END()
#define FUNCTION_DEBUG_PARAM_PTR(typeName, param) \
FUNCTION_DEBUG_PARAM_BASE_BEGIN(); \
stackTraceParamAdd(ptrToLog(param, typeName, stackTraceParamBuffer(#param), STACK_TRACE_PARAM_MAX )); \
FUNCTION_DEBUG_PARAM_BASE_END()
/***********************************************************************************************************************************
Functions and macros to render various data types
***********************************************************************************************************************************/
size_t objToLog(const void *object, const char *objectName, char *buffer, size_t bufferSize);
size_t ptrToLog(const void *pointer, const char *pointerName, char *buffer, size_t bufferSize);
size_t strzToLog(const char *string, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_BOOL_TYPE \
bool
#define FUNCTION_DEBUG_BOOL_FORMAT(value, buffer, bufferSize) \
cvtBoolToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_BOOLP_TYPE \
bool *
#define FUNCTION_DEBUG_BOOLP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "bool *", buffer, bufferSize)
#define FUNCTION_DEBUG_CHARP_TYPE \
char *
#define FUNCTION_DEBUG_CHARP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "char *", buffer, bufferSize)
#define FUNCTION_DEBUG_CONST_CHARPP_TYPE \
const char **
#define FUNCTION_DEBUG_CONST_CHARPP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "char **", buffer, bufferSize)
#define FUNCTION_DEBUG_CHARPY_TYPE \
char *[]
#define FUNCTION_DEBUG_CHARPY_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "char *[]", buffer, bufferSize)
#define FUNCTION_DEBUG_DOUBLE_TYPE \
double
#define FUNCTION_DEBUG_DOUBLE_FORMAT(value, buffer, bufferSize) \
cvtDoubleToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_DOUBLEP_TYPE \
double *
#define FUNCTION_DEBUG_DOUBLEP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "double *", buffer, bufferSize)
#define FUNCTION_DEBUG_INT_TYPE \
int
#define FUNCTION_DEBUG_INT_FORMAT(value, buffer, bufferSize) \
cvtIntToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_INTP_TYPE \
int *
#define FUNCTION_DEBUG_INTP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "int *", buffer, bufferSize)
#define FUNCTION_DEBUG_INT64_TYPE \
int64_t
#define FUNCTION_DEBUG_INT64_FORMAT(value, buffer, bufferSize) \
cvtInt64ToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_ENUM_TYPE \
unsigned int
#define FUNCTION_DEBUG_ENUM_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_UINT_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_FUNCTIONP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value == NULL ? NULL : (void *)1, "function *", buffer, bufferSize)
#define FUNCTION_DEBUG_MODE_TYPE \
mode_t
#define FUNCTION_DEBUG_MODE_FORMAT(value, buffer, bufferSize) \
cvtModeToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_UCHARP_TYPE \
unsigned char *
#define FUNCTION_DEBUG_UCHARP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "unsigned char *", buffer, bufferSize)
#define FUNCTION_DEBUG_SIZE_TYPE \
size_t
#define FUNCTION_DEBUG_SIZE_FORMAT(value, buffer, bufferSize) \
cvtSizeToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_UINT_TYPE \
unsigned int
#define FUNCTION_DEBUG_UINT_FORMAT(value, buffer, bufferSize) \
cvtUIntToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_UINT16_TYPE \
uint16_t
#define FUNCTION_DEBUG_UINT16_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_UINT_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_UINT32_TYPE \
uint32_t
#define FUNCTION_DEBUG_UINT32_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_UINT_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_UINT64_TYPE \
uint64_t
#define FUNCTION_DEBUG_UINT64_FORMAT(value, buffer, bufferSize) \
cvtUInt64ToZ(value, buffer, bufferSize)
#define FUNCTION_DEBUG_VOIDP_TYPE \
void *
#define FUNCTION_DEBUG_VOIDP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "void *", buffer, bufferSize)
#define FUNCTION_DEBUG_VOIDPP_TYPE \
void **
#define FUNCTION_DEBUG_VOIDPP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "void **", buffer, bufferSize)
#define FUNCTION_DEBUG_STRINGZ_TYPE \
const char *
#define FUNCTION_DEBUG_STRINGZ_FORMAT(value, buffer, bufferSize) \
strzToLog(value, buffer, bufferSize)
/***********************************************************************************************************************************
Assert function to be used with function debugging
The assert statement is compiled into production code but only runs when the log level >= debug
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_ASSERT(condition) \
do \
{ \
if (!(condition)) \
THROW_FMT(AssertError, "function debug assertion '%s' failed", #condition); \
} \
while (0)
/***********************************************************************************************************************************
Macros to return function results (or void)
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_RESULT(typeMacroPrefix, result) \
do \
{ \
FUNCTION_DEBUG_##typeMacroPrefix##_TYPE FUNCTION_DEBUG_RESULT_result = result; \
\
STACK_TRACE_POP(); \
\
if (logWill(FUNCTION_DEBUG_LEVEL())) \
{ \
char buffer[STACK_TRACE_PARAM_MAX]; \
\
FUNCTION_DEBUG_##typeMacroPrefix##_FORMAT(FUNCTION_DEBUG_RESULT_result, buffer, sizeof(buffer)); \
LOG(FUNCTION_DEBUG_LEVEL(), 0, "=> %s", buffer); \
} \
\
return FUNCTION_DEBUG_RESULT_result; \
} \
while(0)
#define FUNCTION_DEBUG_RESULT_VOID() \
do \
{ \
STACK_TRACE_POP(); \
\
LOG_WILL(FUNCTION_DEBUG_LEVEL(), 0, "=> void"); \
} \
while(0)
/***********************************************************************************************************************************
Function Test Macros
In debug builds these macros will update the stack trace with function names and parameters but not log. In production builds all
test macros are compiled out.
***********************************************************************************************************************************/
#ifdef DEBUG
#define FUNCTION_TEST_BEGIN() \
if (stackTraceTest()) \
{ \
STACK_TRACE_PUSH(logLevelDebug); \
stackTraceParamLog()
#define FUNCTION_TEST_PARAM(typeMacroPrefix, param) \
FUNCTION_DEBUG_PARAM(typeMacroPrefix, param)
#define FUNCTION_TEST_PARAM_PTR(typeName, param) \
FUNCTION_DEBUG_PARAM_PTR(typeName, param)
#define FUNCTION_TEST_END() \
}
#define FUNCTION_TEST_VOID() \
FUNCTION_TEST_BEGIN(); \
FUNCTION_TEST_END();
#define FUNCTION_TEST_ASSERT(condition) \
do \
{ \
if (!(condition)) \
THROW_FMT(AssertError, "function test assertion '%s' failed", #condition); \
} \
while (0)
#define FUNCTION_TEST_RESULT(typeMacroPrefix, result) \
do \
{ \
FUNCTION_DEBUG_##typeMacroPrefix##_TYPE FUNCTION_DEBUG_RESULT_result = result; \
\
if (stackTraceTest()) \
STACK_TRACE_POP(); \
\
return FUNCTION_DEBUG_RESULT_result; \
} \
while(0);
#define FUNCTION_TEST_RESULT_VOID() \
do \
{ \
if (stackTraceTest()) \
STACK_TRACE_POP(); \
} \
while(0);
#else
#define FUNCTION_TEST_BEGIN()
#define FUNCTION_TEST_PARAM(typeMacroPrefix, param)
#define FUNCTION_TEST_PARAM_PTR(typeName, param)
#define FUNCTION_TEST_END()
#define FUNCTION_TEST_VOID()
#define FUNCTION_TEST_ASSERT(condition)
#define FUNCTION_TEST_RESULT(typeMacroPrefix, result) \
return result
#define FUNCTION_TEST_RESULT_VOID()
#endif
#endif #endif

View File

@@ -6,6 +6,7 @@ Binary to String Encode/Decode
#include "common/encode.h" #include "common/encode.h"
#include "common/encode/base64.h" #include "common/encode/base64.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -20,10 +21,19 @@ Encode binary data to a printable string
void void
encodeToStr(EncodeType encodeType, const unsigned char *source, size_t sourceSize, char *destination) encodeToStr(EncodeType encodeType, const unsigned char *source, size_t sourceSize, char *destination)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(UCHARP, source);
FUNCTION_TEST_PARAM(SIZE, sourceSize);
FUNCTION_TEST_PARAM(CHARP, destination);
FUNCTION_TEST_END();
if (encodeType == encodeBase64) if (encodeType == encodeBase64)
encodeToStrBase64(source, sourceSize, destination); encodeToStrBase64(source, sourceSize, destination);
else else
ENCODE_TYPE_INVALID_ERROR(encodeType); ENCODE_TYPE_INVALID_ERROR(encodeType);
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -32,6 +42,11 @@ Size of the string returned by encodeToStr()
size_t size_t
encodeToStrSize(EncodeType encodeType, size_t sourceSize) encodeToStrSize(EncodeType encodeType, size_t sourceSize)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(SIZE, sourceSize);
FUNCTION_TEST_END();
size_t destinationSize = 0; size_t destinationSize = 0;
if (encodeType == encodeBase64) if (encodeType == encodeBase64)
@@ -39,7 +54,7 @@ encodeToStrSize(EncodeType encodeType, size_t sourceSize)
else else
ENCODE_TYPE_INVALID_ERROR(encodeType); ENCODE_TYPE_INVALID_ERROR(encodeType);
return destinationSize; FUNCTION_TEST_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -48,10 +63,18 @@ Decode a string to binary data
void void
decodeToBin(EncodeType encodeType, const char *source, unsigned char *destination) decodeToBin(EncodeType encodeType, const char *source, unsigned char *destination)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_PARAM(UCHARP, destination);
FUNCTION_TEST_END();
if (encodeType == encodeBase64) if (encodeType == encodeBase64)
decodeToBinBase64(source, destination); decodeToBinBase64(source, destination);
else else
ENCODE_TYPE_INVALID_ERROR(encodeType); ENCODE_TYPE_INVALID_ERROR(encodeType);
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -60,6 +83,11 @@ Size of the binary data returned by decodeToBin()
size_t size_t
decodeToBinSize(EncodeType encodeType, const char *source) decodeToBinSize(EncodeType encodeType, const char *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_END();
size_t destinationSize = 0; size_t destinationSize = 0;
if (encodeType == encodeBase64) if (encodeType == encodeBase64)
@@ -67,7 +95,7 @@ decodeToBinSize(EncodeType encodeType, const char *source)
else else
ENCODE_TYPE_INVALID_ERROR(encodeType); ENCODE_TYPE_INVALID_ERROR(encodeType);
return destinationSize; FUNCTION_TEST_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -76,6 +104,11 @@ Check that the encoded string is valid
bool bool
decodeToBinValid(EncodeType encodeType, const char *source) decodeToBinValid(EncodeType encodeType, const char *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_END();
bool valid = true; bool valid = true;
TRY_BEGIN() TRY_BEGIN()
@@ -88,7 +121,7 @@ decodeToBinValid(EncodeType encodeType, const char *source)
} }
TRY_END(); TRY_END();
return valid; FUNCTION_TEST_RESULT(BOOL, valid);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -97,8 +130,15 @@ Validate the encoded string
void void
decodeToBinValidate(EncodeType encodeType, const char *source) decodeToBinValidate(EncodeType encodeType, const char *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, encodeType);
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_END();
if (encodeType == encodeBase64) if (encodeType == encodeBase64)
decodeToBinValidateBase64(source); decodeToBinValidateBase64(source);
else else
ENCODE_TYPE_INVALID_ERROR(encodeType); ENCODE_TYPE_INVALID_ERROR(encodeType);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -4,6 +4,7 @@ Base64 Binary to String Encode/Decode
#include <string.h> #include <string.h>
#include "common/encode/base64.h" #include "common/encode/base64.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -14,6 +15,15 @@ static const char encodeBase64Lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl
void void
encodeToStrBase64(const unsigned char *source, size_t sourceSize, char *destination) encodeToStrBase64(const unsigned char *source, size_t sourceSize, char *destination)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, source);
FUNCTION_TEST_PARAM(SIZE, sourceSize);
FUNCTION_TEST_PARAM(CHARP, destination);
FUNCTION_TEST_ASSERT(source != NULL);
FUNCTION_TEST_ASSERT(destination != NULL);
FUNCTION_TEST_END();
unsigned int destinationIdx = 0; unsigned int destinationIdx = 0;
// Encode the string from three bytes to four characters // Encode the string from three bytes to four characters
@@ -56,6 +66,8 @@ encodeToStrBase64(const unsigned char *source, size_t sourceSize, char *destinat
// Zero-terminate the string // Zero-terminate the string
destination[destinationIdx] = 0; destination[destinationIdx] = 0;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -64,6 +76,10 @@ Size of the destination param required by encodeToStrBase64() minus space for th
size_t size_t
encodeToStrSizeBase64(size_t sourceSize) encodeToStrSizeBase64(size_t sourceSize)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, sourceSize);
FUNCTION_TEST_END();
// Calculate how many groups of three are in the source // Calculate how many groups of three are in the source
size_t encodeGroupTotal = sourceSize / 3; size_t encodeGroupTotal = sourceSize / 3;
@@ -72,7 +88,7 @@ encodeToStrSizeBase64(size_t sourceSize)
encodeGroupTotal++; encodeGroupTotal++;
// Four characters are needed to encode each group // Four characters are needed to encode each group
return encodeGroupTotal * 4; FUNCTION_TEST_RESULT(SIZE, encodeGroupTotal * 4);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -101,6 +117,11 @@ static const int decodeBase64Lookup[256] =
void void
decodeToBinBase64(const char *source, unsigned char *destination) decodeToBinBase64(const char *source, unsigned char *destination)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_PARAM(UCHARP, destination);
FUNCTION_TEST_END();
// Validate encoded string // Validate encoded string
decodeToBinValidateBase64(source); decodeToBinValidateBase64(source);
@@ -127,6 +148,8 @@ decodeToBinBase64(const char *source, unsigned char *destination)
(((decodeBase64Lookup[(int)source[sourceIdx + 2]] << 6) & 0xc0) | decodeBase64Lookup[(int)source[sourceIdx + 3]]); (((decodeBase64Lookup[(int)source[sourceIdx + 2]] << 6) & 0xc0) | decodeBase64Lookup[(int)source[sourceIdx + 3]]);
} }
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -135,6 +158,10 @@ Size of the destination param required by decodeToBinBase64()
size_t size_t
decodeToBinSizeBase64(const char *source) decodeToBinSizeBase64(const char *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_END();
// Validate encoded string // Validate encoded string
decodeToBinValidateBase64(source); decodeToBinValidateBase64(source);
@@ -152,7 +179,7 @@ decodeToBinSizeBase64(const char *source)
destinationSize--; destinationSize--;
} }
return destinationSize; FUNCTION_TEST_RESULT(SIZE, destinationSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -161,6 +188,10 @@ Validate the encoded string
void void
decodeToBinValidateBase64(const char *source) decodeToBinValidateBase64(const char *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, source);
FUNCTION_TEST_END();
// Check for the correct length // Check for the correct length
size_t sourceSize = strlen(source); size_t sourceSize = strlen(source);
@@ -188,4 +219,6 @@ decodeToBinValidateBase64(const char *source)
THROW_FMT(FormatError, "base64 invalid character found at position %u", sourceIdx); THROW_FMT(FormatError, "base64 invalid character found at position %u", sourceIdx);
} }
} }
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -7,6 +7,7 @@ Error Handler
#include <string.h> #include <string.h>
#include "common/error.h" #include "common/error.h"
#include "common/stackTrace.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Represents an error type Represents an error type
@@ -38,7 +39,7 @@ typedef enum {errorStateBegin, errorStateTry, errorStateCatch, errorStateFinal,
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Track error handling Track error handling
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
struct static struct
{ {
// Array of jump buffers // Array of jump buffers
jmp_buf jumpList[ERROR_TRY_MAX]; jmp_buf jumpList[ERROR_TRY_MAX];
@@ -57,8 +58,10 @@ struct
{ {
const ErrorType *errorType; // Error type const ErrorType *errorType; // Error type
const char *fileName; // Source file where the error occurred const char *fileName; // Source file where the error occurred
const char *functionName; // Function where the error occurred
int fileLine; // Source file line where the error occurred int fileLine; // Source file line where the error occurred
const char *message; // Description of the error const char *message; // Description of the error
const char *stackTrace; // Stack trace
} error; } error;
} errorContext; } errorContext;
@@ -75,6 +78,7 @@ The temp buffer is required because the error message being passed might be the
static char messageBuffer[ERROR_MESSAGE_BUFFER_SIZE]; static char messageBuffer[ERROR_MESSAGE_BUFFER_SIZE];
static char messageBufferTemp[ERROR_MESSAGE_BUFFER_SIZE]; static char messageBufferTemp[ERROR_MESSAGE_BUFFER_SIZE];
static char stackTraceBuffer[ERROR_MESSAGE_BUFFER_SIZE];
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Error type code Error type code
@@ -128,6 +132,14 @@ errorTypeParent(const ErrorType *errorType)
return errorType->parentType; return errorType->parentType;
} }
/***********************************************************************************************************************************
Get the depth of the current try statement (0 if none)
***********************************************************************************************************************************/
unsigned int errorTryDepth()
{
return (unsigned int)errorContext.tryTotal;
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Does the child error type extend the parent error type? Does the child error type extend the parent error type?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -177,6 +189,15 @@ errorFileName()
return errorContext.error.fileName; return errorContext.error.fileName;
} }
/***********************************************************************************************************************************
Error function name
***********************************************************************************************************************************/
const char *
errorFunctionName()
{
return errorContext.error.functionName;
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Error file line number Error file line number
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -204,6 +225,15 @@ errorName()
return errorTypeName(errorType()); return errorTypeName(errorType());
} }
/***********************************************************************************************************************************
Error stack trace
***********************************************************************************************************************************/
const char *
errorStackTrace()
{
return errorContext.error.stackTrace;
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Is this error an instance of the error type? Is this error an instance of the error type?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -265,11 +295,11 @@ errorInternalJump()
Begin the try block Begin the try block
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool bool
errorInternalTry(const char *fileName, int fileLine) errorInternalTry(const char *fileName, const char *functionName, int fileLine)
{ {
// If try total has been exceeded then throw an error // If try total has been exceeded then throw an error
if (errorContext.tryTotal >= ERROR_TRY_MAX) if (errorContext.tryTotal >= ERROR_TRY_MAX)
errorInternalThrowFmt(&AssertError, fileName, fileLine, "too many nested try blocks"); errorInternalThrowFmt(&AssertError, fileName, functionName, fileLine, "too many nested try blocks");
// Increment try total // Increment try total
errorContext.tryTotal++; errorContext.tryTotal++;
@@ -315,6 +345,9 @@ errorInternalProcess(bool catch)
errorContext.tryList[errorContext.tryTotal].uncaught = false; errorContext.tryList[errorContext.tryTotal].uncaught = false;
return true; return true;
} }
// Else if just entering error state clean up the stack
else if (errorContext.tryList[errorContext.tryTotal].state == errorStateTry)
stackTraceClean(errorTryDepth());
// Increment the state // Increment the state
errorContext.tryList[errorContext.tryTotal].state++; errorContext.tryList[errorContext.tryTotal].state++;
@@ -345,23 +378,34 @@ errorInternalProcess(bool catch)
Throw an error Throw an error
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void void
errorInternalThrow(const ErrorType *errorType, const char *fileName, int fileLine, const char *message) errorInternalThrow(const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
{ {
// Setup error data // Setup error data
errorContext.error.errorType = errorType; errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName; errorContext.error.fileName = fileName;
errorContext.error.functionName = functionName;
errorContext.error.fileLine = fileLine; errorContext.error.fileLine = fileLine;
// Assign message to the error // Assign message to the error
strcpy(messageBuffer, message); strcpy(messageBuffer, message);
errorContext.error.message = (const char *)messageBuffer; errorContext.error.message = (const char *)messageBuffer;
// Generate the stack trace for the error
if (stackTraceToZ(
stackTraceBuffer, sizeof(stackTraceBuffer), fileName, functionName, (unsigned int)fileLine) >= sizeof(stackTraceBuffer))
{
// Indicate that the stack trace was truncated
}
errorContext.error.stackTrace = (const char *)stackTraceBuffer;
// Propogate the error // Propogate the error
errorInternalPropagate(); errorInternalPropagate();
} }
void void
errorInternalThrowFmt(const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...) errorInternalThrowFmt(
const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
{ {
// Format message // Format message
va_list argument; va_list argument;
@@ -369,39 +413,26 @@ errorInternalThrowFmt(const ErrorType *errorType, const char *fileName, int file
vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument); vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument);
va_end(argument); va_end(argument);
errorInternalThrow(errorType, fileName, fileLine, messageBufferTemp); errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Throw a system error Throw a system error
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void void
errorInternalThrowSys(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *message) errorInternalThrowSys(
int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
{ {
// Setup error data // Format message with system message appended
errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName;
errorContext.error.fileLine = fileLine;
// Append the system message
snprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, "%s: [%d] %s", message, errNo, strerror(errNo)); snprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, "%s: [%d] %s", message, errNo, strerror(errNo));
// Assign message to the error errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
strcpy(messageBuffer, messageBufferTemp);
errorContext.error.message = (const char *)messageBuffer;
// Propogate the error
errorInternalPropagate();
} }
void void
errorInternalThrowSysFmt(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...) errorInternalThrowSysFmt(
int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
{ {
// Setup error data
errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName;
errorContext.error.fileLine = fileLine;
// Format message // Format message
va_list argument; va_list argument;
va_start(argument, format); va_start(argument, format);
@@ -411,10 +442,5 @@ errorInternalThrowSysFmt(int errNo, const ErrorType *errorType, const char *file
// Append the system message // Append the system message
snprintf(messageBufferTemp + messageSize, ERROR_MESSAGE_BUFFER_SIZE - 1 - messageSize, ": [%d] %s", errNo, strerror(errNo)); snprintf(messageBufferTemp + messageSize, ERROR_MESSAGE_BUFFER_SIZE - 1 - messageSize, ": [%d] %s", errNo, strerror(errNo));
// Assign message to the error errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
strcpy(messageBuffer, messageBufferTemp);
errorContext.error.message = (const char *)messageBuffer;
// Propogate the error
errorInternalPropagate();
} }

View File

@@ -68,10 +68,17 @@ Functions to get information about the current error
const ErrorType *errorType(); const ErrorType *errorType();
int errorCode(); int errorCode();
const char *errorFileName(); const char *errorFileName();
const char *errorFunctionName();
int errorFileLine(); int errorFileLine();
bool errorInstanceOf(const ErrorType *errorTypeTest);
const char *errorMessage(); const char *errorMessage();
const char *errorName(); const char *errorName();
bool errorInstanceOf(const ErrorType *errorTypeTest); const char *errorStackTrace();
/***********************************************************************************************************************************
Functions to get information about the try stack
***********************************************************************************************************************************/
unsigned int errorTryDepth();
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Begin a block where errors can be thrown Begin a block where errors can be thrown
@@ -79,7 +86,7 @@ Begin a block where errors can be thrown
#define TRY_BEGIN() \ #define TRY_BEGIN() \
do \ do \
{ \ { \
if (errorInternalTry(__FILE__, __LINE__) && setjmp(*errorInternalJump()) >= 0) \ if (errorInternalTry(__FILE__, __func__, __LINE__) && setjmp(*errorInternalJump()) >= 0) \
{ \ { \
while (errorInternalProcess(false)) \ while (errorInternalProcess(false)) \
if (errorInternalStateTry()) if (errorInternalStateTry())
@@ -118,39 +125,39 @@ error information to stderr.
The seldom used "THROWP" variants allow an error to be thrown with a pointer to the error type. The seldom used "THROWP" variants allow an error to be thrown with a pointer to the error type.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define THROW(errorType, message) \ #define THROW(errorType, message) \
errorInternalThrow(&errorType, __FILE__, __LINE__, message) errorInternalThrow(&errorType, __FILE__, __func__, __LINE__, message)
#define THROW_FMT(errorType, ...) \ #define THROW_FMT(errorType, ...) \
errorInternalThrowFmt(&errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowFmt(&errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define THROWP(errorType, message) \ #define THROWP(errorType, message) \
errorInternalThrow(errorType, __FILE__, __LINE__, message) errorInternalThrow(errorType, __FILE__, __func__, __LINE__, message)
#define THROWP_FMT(errorType, ...) \ #define THROWP_FMT(errorType, ...) \
errorInternalThrowFmt(errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowFmt(errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define THROW_CODE(errorCode, message) \ #define THROW_CODE(errorCode, message) \
errorInternalThrow(errorTypeFromCode(errorCode), __FILE__, __LINE__, message) errorInternalThrow(errorTypeFromCode(errorCode), __FILE__, __func__, __LINE__, message)
#define THROW_CODE_FMT(errorCode, ...) \ #define THROW_CODE_FMT(errorCode, ...) \
errorInternalThrowFmt(errorTypeFromCode(errorCode), __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowFmt(errorTypeFromCode(errorCode), __FILE__, __func__, __LINE__, __VA_ARGS__)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Throw an error when a system call fails Throw an error when a system call fails
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define THROW_SYS_ERROR(errorType, message) \ #define THROW_SYS_ERROR(errorType, message) \
errorInternalThrowSys(errno, &errorType, __FILE__, __LINE__, message) errorInternalThrowSys(errno, &errorType, __FILE__, __func__, __LINE__, message)
#define THROW_SYS_ERROR_FMT(errorType, ...) \ #define THROW_SYS_ERROR_FMT(errorType, ...) \
errorInternalThrowSysFmt(errno, &errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowSysFmt(errno, &errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR(errorType, message) \ #define THROWP_SYS_ERROR(errorType, message) \
errorInternalThrowSys(errno, errorType, __FILE__, __LINE__, message) errorInternalThrowSys(errno, errorType, __FILE__, __func__, __LINE__, message)
#define THROWP_SYS_ERROR_FMT(errorType, ...) \ #define THROWP_SYS_ERROR_FMT(errorType, ...) \
errorInternalThrowSysFmt(errno, errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowSysFmt(errno, errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define THROW_SYS_ERROR_CODE(errNo, errorType, message) \ #define THROW_SYS_ERROR_CODE(errNo, errorType, message) \
errorInternalThrowSys(errNo, &errorType, __FILE__, __LINE__, message) errorInternalThrowSys(errNo, &errorType, __FILE__, __func__, __LINE__, message)
#define THROW_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \ #define THROW_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \
errorInternalThrowSysFmt(errNo, &errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowSysFmt(errNo, &errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR_CODE(errNo, errorType, message) \ #define THROWP_SYS_ERROR_CODE(errNo, errorType, message) \
errorInternalThrowSys(errNo, errorType, __FILE__, __LINE__, message) errorInternalThrowSys(errNo, errorType, __FILE__, __func__, __LINE__, message)
#define THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \ #define THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \
errorInternalThrowSysFmt(errNo, errorType, __FILE__, __LINE__, __VA_ARGS__) errorInternalThrowSysFmt(errNo, errorType, __FILE__, __func__, __LINE__, __VA_ARGS__)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Rethrow the current error Rethrow the current error
@@ -163,7 +170,7 @@ Internal functions
These functions are used by the macros to implement the error handler and should never be called independently. These functions are used by the macros to implement the error handler and should never be called independently.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool errorInternalTry(const char *fileName, int fileLine); bool errorInternalTry(const char *fileName, const char *functionName, int fileLine);
jmp_buf *errorInternalJump(); jmp_buf *errorInternalJump();
bool errorInternalStateTry(); bool errorInternalStateTry();
bool errorInternalStateCatch(const ErrorType *errorTypeCatch); bool errorInternalStateCatch(const ErrorType *errorTypeCatch);
@@ -171,14 +178,24 @@ bool errorInternalStateFinal();
bool errorInternalProcess(bool catch); bool errorInternalProcess(bool catch);
void errorInternalPropagate() __attribute__((__noreturn__)); void errorInternalPropagate() __attribute__((__noreturn__));
void errorInternalThrow( void errorInternalThrow(
const ErrorType *errorType, const char *fileName, int fileLine, const char *message) __attribute__((__noreturn__)); const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
__attribute__((__noreturn__));
void errorInternalThrowFmt( void errorInternalThrowFmt(
const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...) const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
__attribute__((__noreturn__)) __attribute__((format(printf, 4, 5))); __attribute__((format(printf, 5, 6))) __attribute__((__noreturn__));
void errorInternalThrowSys( void errorInternalThrowSys(
int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *message); int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
__attribute__((__noreturn__));
void errorInternalThrowSysFmt( void errorInternalThrowSysFmt(
int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...) int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
__attribute__((format(printf, 5, 6))); __attribute__((format(printf, 6, 7))) __attribute__((__noreturn__));
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_ERROR_TYPE_TYPE \
ErrorType *
#define FUNCTION_DEBUG_ERROR_TYPE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "ErrorType", buffer, bufferSize)
#endif #endif

View File

@@ -5,6 +5,7 @@ Exit Routines
#include <string.h> #include <string.h>
#include "command/command.h" #include "command/command.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/exit.h" #include "common/exit.h"
#include "common/lock.h" #include "common/lock.h"
@@ -18,6 +19,10 @@ Return signal names
static const char * static const char *
exitSignalName(int signalType) exitSignalName(int signalType)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, signalType);
FUNCTION_TEST_END();
const char *name = NULL; const char *name = NULL;
switch (signalType) switch (signalType)
@@ -44,7 +49,7 @@ exitSignalName(int signalType)
THROW(AssertError, "no name for signal none"); THROW(AssertError, "no name for signal none");
} }
return name; FUNCTION_TEST_RESULT(STRINGZ, name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -53,7 +58,13 @@ Catch signals
static void static void
exitOnSignal(int signalType) exitOnSignal(int signalType)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(INT, signalType);
FUNCTION_DEBUG_END();
exit(exitSafe(errorTypeCode(&TermError), false, (SignalType)signalType)); exit(exitSafe(errorTypeCode(&TermError), false, (SignalType)signalType));
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -62,9 +73,13 @@ Setup signal handlers
void void
exitInit() exitInit()
{ {
FUNCTION_DEBUG_VOID(logLevelTrace);
signal(SIGHUP, exitOnSignal); signal(SIGHUP, exitOnSignal);
signal(SIGINT, exitOnSignal); signal(SIGINT, exitOnSignal);
signal(SIGTERM, exitOnSignal); signal(SIGTERM, exitOnSignal);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -73,12 +88,37 @@ Do cleanup and return result code
int int
exitSafe(int result, bool error, SignalType signalType) exitSafe(int result, bool error, SignalType signalType)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(INT, result);
FUNCTION_DEBUG_PARAM(BOOL, error);
FUNCTION_DEBUG_PARAM(ENUM, signalType);
FUNCTION_DEBUG_END();
// Report error if one was thrown // Report error if one was thrown
if (error) if (error)
{ {
// Don't log the error if it has already been logged by Perl // Don't log the error if it has already been logged by Perl
if (strcmp(errorMessage(), PERL_EMBED_ERROR) != 0) if (strcmp(errorMessage(), PERL_EMBED_ERROR) != 0)
LOG_ANY(errorCode() == errorTypeCode(&AssertError) ? logLevelAssert : logLevelError, errorCode(), errorMessage()); {
LogLevel logLevel = errorCode() == errorTypeCode(&AssertError) ? logLevelAssert : logLevelError;
// Assert errors always output a stack trace
if (logLevel == logLevelAssert)
LOG(logLevel, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(), errorStackTrace());
else
{
// Log just the error to non-debug levels
LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, logLevelDetail, errorCode(), errorMessage());
// Log the stack trace debug levels
if (logWill(logLevelDebug))
{
LOG_INTERNAL(
logLevel, logLevelDebug, LOG_LEVEL_MAX, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(),
errorStackTrace());
}
}
}
result = errorCode(); result = errorCode();
} }
@@ -126,5 +166,5 @@ exitSafe(int result, bool error, SignalType signalType)
} }
// Return result - caller should immediate pass this result to exit() // Return result - caller should immediate pass this result to exit()
return result; FUNCTION_DEBUG_RESULT(INT, result);
} }

View File

@@ -3,6 +3,7 @@ Fork Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <unistd.h> #include <unistd.h>
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -12,6 +13,8 @@ startup because the parent process may continue to run and perform work for some
void void
forkDetach() forkDetach()
{ {
FUNCTION_DEBUG_VOID(logLevelTrace);
if (chdir("/") == -1) // {uncoverable - should never fail} if (chdir("/") == -1) // {uncoverable - should never fail}
THROW_SYS_ERROR(PathMissingError, "unable to change directory to '/'"); // {uncoverable+} THROW_SYS_ERROR(PathMissingError, "unable to change directory to '/'"); // {uncoverable+}
@@ -26,4 +29,6 @@ forkDetach()
if (close(STDERR_FILENO) == -1) // {uncoverable - should never fail} if (close(STDERR_FILENO) == -1) // {uncoverable - should never fail}
THROW_SYS_ERROR(FileCloseError, "unable to close stderr"); // {uncoverable+} THROW_SYS_ERROR(FileCloseError, "unable to close stderr"); // {uncoverable+}
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -5,6 +5,7 @@ Ini Handler
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/ini.h" #include "common/ini.h"
#include "common/type/keyValue.h" #include "common/type/keyValue.h"
@@ -49,6 +50,16 @@ Internal function to get an ini value
static const Variant * static const Variant *
iniGetInternal(const Ini *this, const String *section, const String *key) iniGetInternal(const Ini *this, const String *section, const String *key)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, section);
FUNCTION_TEST_PARAM(STRING, key);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(section != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
const Variant *result = NULL; const Variant *result = NULL;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -62,7 +73,7 @@ iniGetInternal(const Ini *this, const String *section, const String *key)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_TEST_RESULT(CONST_VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -71,6 +82,16 @@ Get an ini value -- error if it does not exist
const Variant * const Variant *
iniGet(const Ini *this, const String *section, const String *key) iniGet(const Ini *this, const String *section, const String *key)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, section);
FUNCTION_TEST_PARAM(STRING, key);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(section != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
// Get the value // Get the value
const Variant *result = iniGetInternal(this, section, key); const Variant *result = iniGetInternal(this, section, key);
@@ -79,6 +100,8 @@ iniGet(const Ini *this, const String *section, const String *key)
THROW_FMT(FormatError, "section '%s', key '%s' does not exist", strPtr(section), strPtr(key)); THROW_FMT(FormatError, "section '%s', key '%s' does not exist", strPtr(section), strPtr(key));
return result; return result;
FUNCTION_TEST_RESULT(CONST_VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -87,6 +110,17 @@ Get an ini value -- if it does not exist then return specified default
const Variant * const Variant *
iniGetDefault(const Ini *this, const String *section, const String *key, Variant *defaultValue) iniGetDefault(const Ini *this, const String *section, const String *key, Variant *defaultValue)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, section);
FUNCTION_TEST_PARAM(STRING, key);
FUNCTION_TEST_PARAM(VARIANT, defaultValue);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(section != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
// Get the value // Get the value
const Variant *result = iniGetInternal(this, section, key); const Variant *result = iniGetInternal(this, section, key);
@@ -94,7 +128,7 @@ iniGetDefault(const Ini *this, const String *section, const String *key, Variant
if (result == NULL) if (result == NULL)
result = defaultValue; result = defaultValue;
return result; FUNCTION_TEST_RESULT(CONST_VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -103,6 +137,14 @@ Get a list of keys for a section
StringList * StringList *
iniSectionKeyList(const Ini *this, const String *section) iniSectionKeyList(const Ini *this, const String *section)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, section);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(section != NULL);
FUNCTION_TEST_END();
StringList *result = NULL; StringList *result = NULL;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -121,7 +163,7 @@ iniSectionKeyList(const Ini *this, const String *section)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_TEST_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -130,6 +172,13 @@ Parse ini from a string
void void
iniParse(Ini *this, const String *content) iniParse(Ini *this, const String *content)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, content);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
{ {
kvFree(this->store); kvFree(this->store);
@@ -195,6 +244,8 @@ iniParse(Ini *this, const String *content)
} }
} }
MEM_CONTEXT_END() MEM_CONTEXT_END()
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -203,6 +254,14 @@ Load ini from a file
void void
iniLoad(Ini *this, const String *fileName) iniLoad(Ini *this, const String *fileName)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, fileName);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(fileName != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
{ {
// Set the filename // Set the filename
@@ -215,6 +274,8 @@ iniLoad(Ini *this, const String *fileName)
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
} }
MEM_CONTEXT_END() MEM_CONTEXT_END()
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -223,6 +284,18 @@ Set an ini value
void void
iniSet(Ini *this, const String *section, const String *key, const Variant *value) iniSet(Ini *this, const String *section, const String *key, const Variant *value)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_PARAM(STRING, section);
FUNCTION_TEST_PARAM(STRING, key);
FUNCTION_TEST_PARAM(VARIANT, value);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(section != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
Variant *sectionKey = varNewStr(section); Variant *sectionKey = varNewStr(section);
@@ -234,6 +307,8 @@ iniSet(Ini *this, const String *section, const String *key, const Variant *value
kvAdd(sectionKv, varNewStr(key), value); kvAdd(sectionKv, varNewStr(key), value);
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -242,5 +317,12 @@ Free the ini
void void
iniFree(Ini *this) iniFree(Ini *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INI, this);
FUNCTION_TEST_END();
if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -24,4 +24,12 @@ void iniSet(Ini *this, const String *section, const String *key, const Variant *
void iniFree(Ini *this); void iniFree(Ini *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_INI_TYPE \
Ini *
#define FUNCTION_DEBUG_INI_FORMAT(value, buffer, bufferSize) \
objToLog(value, "Ini", buffer, bufferSize)
#endif #endif

View File

@@ -3,6 +3,7 @@ Handle IO
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <unistd.h> #include <unistd.h>
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/io/handle.h" #include "common/io/handle.h"
@@ -12,6 +13,15 @@ Write a string to the specified handle
void void
ioHandleWriteOneStr(int handle, const String *string) ioHandleWriteOneStr(int handle, const String *string)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(INT, handle);
FUNCTION_DEBUG_PARAM(STRING, string);
FUNCTION_DEBUG_ASSERT(string != NULL);
FUNCTION_DEBUG_END();
if (write(handle, strPtr(string), strSize(string)) != (int)strSize(string)) if (write(handle, strPtr(string), strSize(string)) != (int)strSize(string))
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write to %zu byte(s) to handle", strSize(string)); THROW_SYS_ERROR_FMT(FileWriteError, "unable to write to %zu byte(s) to handle", strSize(string));
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -8,6 +8,7 @@ Lock Handler
#include <unistd.h> #include <unistd.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/io/handle.h" #include "common/io/handle.h"
#include "common/lock.h" #include "common/lock.h"
#include "common/memContext.h" #include "common/memContext.h"
@@ -38,6 +39,12 @@ Acquire a lock using a file on the local filesystem
static int static int
lockAcquireFile(const String *lockFile, double lockTimeout, bool failOnNoLock) lockAcquireFile(const String *lockFile, double lockTimeout, bool failOnNoLock)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, lockFile);
FUNCTION_DEBUG_PARAM(DOUBLE, lockTimeout);
FUNCTION_DEBUG_PARAM(BOOL, failOnNoLock);
FUNCTION_DEBUG_END();
int result = -1; int result = -1;
// Timeout can't be negative // Timeout can't be negative
@@ -112,7 +119,7 @@ lockAcquireFile(const String *lockFile, double lockTimeout, bool failOnNoLock)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -121,6 +128,11 @@ Release the current lock
static void static void
lockReleaseFile(int lockHandle, const String *lockFile) lockReleaseFile(int lockHandle, const String *lockFile)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(INT, lockHandle);
FUNCTION_DEBUG_PARAM(STRING, lockFile);
FUNCTION_DEBUG_END();
// Can't release lock if there isn't one // Can't release lock if there isn't one
ASSERT_DEBUG(lockHandle != -1); ASSERT_DEBUG(lockHandle != -1);
@@ -128,6 +140,8 @@ lockReleaseFile(int lockHandle, const String *lockFile)
// right before the delete which means the file locked by the other process will get deleted. // right before the delete which means the file locked by the other process will get deleted.
storageRemoveNP(storageLocalWrite(), lockFile); storageRemoveNP(storageLocalWrite(), lockFile);
close(lockHandle); close(lockHandle);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -139,6 +153,14 @@ backup), but the stanza commands all need to lock both.
bool bool
lockAcquire(const String *lockPath, const String *stanza, LockType lockType, double lockTimeout, bool failOnNoLock) lockAcquire(const String *lockPath, const String *stanza, LockType lockType, double lockTimeout, bool failOnNoLock)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, lockPath);
FUNCTION_DEBUG_PARAM(STRING, stanza);
FUNCTION_DEBUG_PARAM(ENUM, lockType);
FUNCTION_DEBUG_PARAM(DOUBLE, lockTimeout);
FUNCTION_DEBUG_PARAM(BOOL, failOnNoLock);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
// Don't allow failures when locking more than one file. This makes cleanup difficult and there are no known use cases. // Don't allow failures when locking more than one file. This makes cleanup difficult and there are no known use cases.
@@ -186,7 +208,7 @@ lockAcquire(const String *lockPath, const String *stanza, LockType lockType, dou
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -196,6 +218,10 @@ and the master process won't try to free it.
bool bool
lockClear(bool failOnNoLock) lockClear(bool failOnNoLock)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(BOOL, failOnNoLock);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
if (lockTypeHeld == lockTypeNone) if (lockTypeHeld == lockTypeNone)
@@ -216,7 +242,7 @@ lockClear(bool failOnNoLock)
result = true; result = true;
} }
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -225,6 +251,10 @@ Release a lock type
bool bool
lockRelease(bool failOnNoLock) lockRelease(bool failOnNoLock)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(BOOL, failOnNoLock);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
if (lockTypeHeld == lockTypeNone) if (lockTypeHeld == lockTypeNone)
@@ -248,5 +278,5 @@ lockRelease(bool failOnNoLock)
result = true; result = true;
} }
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }

View File

@@ -36,25 +36,22 @@ static bool logFileBanner = false;
DEBUG_UNIT_EXTERN bool logTimestamp = false; DEBUG_UNIT_EXTERN bool logTimestamp = false;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Debug Asserts Test Asserts
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) \ #define FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel) \
ASSERT_DEBUG(logLevel > logLevelOff) FUNCTION_TEST_ASSERT(logLevel >= LOG_LEVEL_MIN && logLevel <= LOG_LEVEL_MAX)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Log buffer Log buffer -- used to format log header and message
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define LOG_BUFFER_SIZE 32768 static char logBuffer[LOG_BUFFER_SIZE];
char logBuffer[LOG_BUFFER_SIZE];
char logFormat[LOG_BUFFER_SIZE];
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Convert log level to string and vice versa Convert log level to string and vice versa
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define LOG_LEVEL_TOTAL 9 #define LOG_LEVEL_TOTAL (LOG_LEVEL_MAX + 1)
const char *logLevelList[LOG_LEVEL_TOTAL] = static const char *logLevelList[LOG_LEVEL_TOTAL] =
{ {
"OFF", "OFF",
"ASSERT", "ASSERT",
@@ -70,6 +67,12 @@ const char *logLevelList[LOG_LEVEL_TOTAL] =
LogLevel LogLevel
logLevelEnum(const char *logLevel) logLevelEnum(const char *logLevel)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, logLevel);
FUNCTION_TEST_ASSERT(logLevel != NULL);
FUNCTION_TEST_END();
LogLevel result = logLevelOff; LogLevel result = logLevelOff;
// Search for the log level // Search for the log level
@@ -81,16 +84,19 @@ logLevelEnum(const char *logLevel)
if (result == LOG_LEVEL_TOTAL) if (result == LOG_LEVEL_TOTAL)
THROW_FMT(AssertError, "log level '%s' not found", logLevel); THROW_FMT(AssertError, "log level '%s' not found", logLevel);
return result; FUNCTION_TEST_RESULT(ENUM, result);
} }
const char * const char *
logLevelStr(LogLevel logLevel) logLevelStr(LogLevel logLevel)
{ {
if (logLevel >= LOG_LEVEL_TOTAL) FUNCTION_TEST_BEGIN();
THROW_FMT(AssertError, "invalid log level '%u'", logLevel); FUNCTION_TEST_PARAM(ENUM, logLevel);
return logLevelList[logLevel]; FUNCTION_TEST_ASSERT(logLevel <= LOG_LEVEL_MAX);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, logLevelList[logLevel]);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -99,10 +105,23 @@ Initialize the log system
void void
logInit(LogLevel logLevelStdOutParam, LogLevel logLevelStdErrParam, LogLevel logLevelFileParam, bool logTimestampParam) logInit(LogLevel logLevelStdOutParam, LogLevel logLevelStdErrParam, LogLevel logLevelFileParam, bool logTimestampParam)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevelStdOutParam);
FUNCTION_TEST_PARAM(ENUM, logLevelStdErrParam);
FUNCTION_TEST_PARAM(ENUM, logLevelFileParam);
FUNCTION_TEST_PARAM(BOOL, logTimestampParam);
FUNCTION_TEST_ASSERT(logLevelStdOutParam <= LOG_LEVEL_MAX);
FUNCTION_TEST_ASSERT(logLevelStdErrParam <= LOG_LEVEL_MAX);
FUNCTION_TEST_ASSERT(logLevelFileParam <= LOG_LEVEL_MAX);
FUNCTION_TEST_END();
logLevelStdOut = logLevelStdOutParam; logLevelStdOut = logLevelStdOutParam;
logLevelStdErr = logLevelStdErrParam; logLevelStdErr = logLevelStdErrParam;
logLevelFile = logLevelFileParam; logLevelFile = logLevelFileParam;
logTimestamp = logTimestampParam; logTimestamp = logTimestampParam;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -111,6 +130,12 @@ Set the log file
void void
logFileSet(const char *logFile) logFileSet(const char *logFile)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, logFile);
FUNCTION_TEST_ASSERT(logFile != NULL);
FUNCTION_TEST_END();
// Close the file handle if it is already open // Close the file handle if it is already open
if (logHandleFile != -1) if (logHandleFile != -1)
{ {
@@ -133,6 +158,8 @@ logFileSet(const char *logFile)
// Output the banner on first log message // Output the banner on first log message
logFileBanner = false; logFileBanner = false;
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -143,29 +170,69 @@ This is useful for log messages that are expensive to generate and should be ski
static bool static bool
logWillFile(LogLevel logLevel) logWillFile(LogLevel logLevel)
{ {
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) FUNCTION_TEST_BEGIN();
return logLevel <= logLevelFile && logHandleFile != -1; FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, logLevel <= logLevelFile && logHandleFile != -1);
} }
static bool static bool
logWillStdErr(LogLevel logLevel) logWillStdErr(LogLevel logLevel)
{ {
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) FUNCTION_TEST_BEGIN();
return logLevel <= logLevelStdErr; FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, logLevel <= logLevelStdErr);
} }
static bool static bool
logWillStdOut(LogLevel logLevel) logWillStdOut(LogLevel logLevel)
{ {
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) FUNCTION_TEST_BEGIN();
return logLevel <= logLevelStdOut; FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, logLevel <= logLevelStdOut);
} }
bool bool
logWill(LogLevel logLevel) logWill(LogLevel logLevel)
{ {
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) FUNCTION_TEST_BEGIN();
return logWillStdOut(logLevel) || logWillStdErr(logLevel) || logWillFile(logLevel); FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, logWillStdOut(logLevel) || logWillStdErr(logLevel) || logWillFile(logLevel));
}
/***********************************************************************************************************************************
Determine if the log level is in the specified range
***********************************************************************************************************************************/
static bool
logRange(LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logRangeMin);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logRangeMax);
FUNCTION_TEST_ASSERT(logRangeMin <= logRangeMax);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, logLevel >= logRangeMin && logLevel <= logRangeMax);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -174,17 +241,93 @@ Internal write function that handles errors
static void static void
logWrite(int handle, const char *message, size_t messageSize, const char *errorDetail) logWrite(int handle, const char *message, size_t messageSize, const char *errorDetail)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, handle);
FUNCTION_TEST_PARAM(STRINGZ, message);
FUNCTION_TEST_PARAM(SIZE, messageSize);
FUNCTION_TEST_PARAM(STRINGZ, errorDetail);
FUNCTION_TEST_ASSERT(handle != -1);
FUNCTION_TEST_ASSERT(message != NULL);
FUNCTION_TEST_ASSERT(messageSize != 0);
FUNCTION_TEST_ASSERT(errorDetail != NULL);
FUNCTION_TEST_END();
if ((size_t)write(handle, message, messageSize) != messageSize) if ((size_t)write(handle, message, messageSize) != messageSize)
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write %s", errorDetail); THROW_SYS_ERROR_FMT(FileWriteError, "unable to write %s", errorDetail);
FUNCTION_TEST_RESULT_VOID();
}
/***********************************************************************************************************************************
Write out log message and indent subsequent lines
***********************************************************************************************************************************/
static void
logWriteIndent(int handle, const char *message, size_t indentSize, const char *errorDetail)
{
// Indent buffer -- used to write out indent space without having to loop
static const char indentBuffer[] = " ";
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, handle);
FUNCTION_TEST_PARAM(STRINGZ, message);
FUNCTION_TEST_PARAM(SIZE, indentSize);
FUNCTION_TEST_PARAM(STRINGZ, errorDetail);
FUNCTION_TEST_ASSERT(handle != -1);
FUNCTION_TEST_ASSERT(message != NULL);
FUNCTION_TEST_ASSERT(indentSize > 0 && indentSize < sizeof(indentBuffer));
FUNCTION_TEST_ASSERT(errorDetail != NULL);
FUNCTION_TEST_END();
// Indent all lines after the first
const char *linefeedPtr = strchr(message, '\n');
bool first = true;
while (linefeedPtr != NULL)
{
if (!first)
logWrite(handle, indentBuffer, indentSize, errorDetail);
else
first = false;
logWrite(handle, message, (size_t)(linefeedPtr - message + 1), errorDetail);
message += (size_t)(linefeedPtr - message + 1);
linefeedPtr = strchr(message, '\n');
}
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
General log function General log function
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void void
logInternal(LogLevel logLevel, const char *fileName, const char *functionName, int code, const char *format, ...) logInternal(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, const char *fileName, const char *functionName, int code,
const char *format, ...)
{ {
ASSERT_DEBUG_MESSAGE_LOG_LEVEL_VALID(logLevel) FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_PARAM(STRINGZ, fileName);
FUNCTION_TEST_PARAM(STRINGZ, functionName);
FUNCTION_TEST_PARAM(INT, code);
FUNCTION_TEST_PARAM(STRINGZ, format);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logLevel);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logRangeMin);
FUNCTION_TEST_ASSERT_LOG_LEVEL(logRangeMax);
FUNCTION_TEST_ASSERT(logRangeMin <= logRangeMax);
FUNCTION_TEST_ASSERT(fileName != NULL);
FUNCTION_TEST_ASSERT(functionName != NULL);
FUNCTION_TEST_ASSERT(
(code == 0 && logLevel > logLevelError) || (logLevel == logLevelError && code != errorTypeCode(&AssertError)) ||
(logLevel == logLevelAssert && code == errorTypeCode(&AssertError)));
FUNCTION_TEST_ASSERT(format != NULL);
FUNCTION_TEST_END();
size_t bufferPos = 0; // Current position in the buffer size_t bufferPos = 0; // Current position in the buffer
@@ -194,65 +337,43 @@ logInternal(LogLevel logLevel, const char *fileName, const char *functionName, i
TimeMSec logTimeMSec = timeMSec(); TimeMSec logTimeMSec = timeMSec();
time_t logTimeSec = (time_t)(logTimeMSec / MSEC_PER_SEC); time_t logTimeSec = (time_t)(logTimeMSec / MSEC_PER_SEC);
bufferPos += strftime(logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "%Y-%m-%d %H:%M:%S", localtime(&logTimeSec)); bufferPos += strftime(logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "%Y-%m-%d %H:%M:%S", localtime(&logTimeSec));
bufferPos += (size_t)snprintf( bufferPos += (size_t)snprintf(
logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, ".%03d ", (int)(logTimeMSec % 1000)); logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, ".%03d ", (int)(logTimeMSec % 1000));
} }
// Add process and aligned log level // Add process and aligned log level
bufferPos += (size_t)snprintf( bufferPos += (size_t)snprintf(logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "P00 %*s: ", 6, logLevelStr(logLevel));
logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "P00 %*s: ", 6, logLevelStr(logLevel));
// Position after the timestamp and process id for output to stderr // When writing to stderr the timestamp, process, and log level alignment will be skipped
size_t messageStdErrPos = bufferPos - strlen(logLevelStr(logLevel)) - 2; char *logBufferStdErr = logBuffer + bufferPos - strlen(logLevelStr(logLevel)) - 2;
// Check that error code matches log level // Set the indent size -- this will need to be adjusted for stderr
ASSERT_DEBUG( size_t indentSize = bufferPos;
code == 0 || (logLevel == logLevelError && code != errorTypeCode(&AssertError)) ||
(logLevel == logLevelAssert && code == errorTypeCode(&AssertError)));
// Add code // Add error code
if (code != 0) if (code != 0)
bufferPos += (size_t)snprintf(logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "[%03d]: ", code); bufferPos += (size_t)snprintf(logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "[%03d]: ", code);
// Add debug info // Add debug info
if (logLevel >= logLevelDebug) if (logLevel >= logLevelDebug)
{ {
bufferPos += (size_t)snprintf( // Adding padding for debug and trace levels
logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "%s:%s(): ", fileName, functionName); for (unsigned int paddingIdx = 0; paddingIdx < ((logLevel - logLevelDebug + 1) * 4); paddingIdx++)
{
logBuffer[bufferPos++] = ' ';
indentSize++;
} }
// Format message bufferPos += (size_t)snprintf(
logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "%.*s::%s: ", (int)strlen(fileName) - 2, fileName,
functionName);
}
// Format message -- this will need to be indented later
va_list argumentList; va_list argumentList;
va_start(argumentList, format); va_start(argumentList, format);
if (logLevel <= logLevelStdErr || strchr(format, '\n') == NULL)
bufferPos += (size_t)vsnprintf(logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, format, argumentList); bufferPos += (size_t)vsnprintf(logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, format, argumentList);
else
{
vsnprintf(logFormat, LOG_BUFFER_SIZE, format, argumentList);
// Indent all lines after the first
const char *formatPtr = logFormat;
const char *linefeedPtr = strchr(logFormat, '\n');
int indentSize = 12;
while (linefeedPtr != NULL)
{
strncpy(logBuffer + bufferPos, formatPtr, (size_t)(linefeedPtr - formatPtr + 1));
bufferPos += (size_t)(linefeedPtr - formatPtr + 1);
formatPtr = linefeedPtr + 1;
linefeedPtr = strchr(formatPtr, '\n');
for (int indentIdx = 0; indentIdx < indentSize; indentIdx++)
logBuffer[bufferPos++] = ' ';
}
strcpy(logBuffer + bufferPos, formatPtr);
bufferPos += strlen(formatPtr);
}
va_end(argumentList); va_end(argumentList);
// Add linefeed // Add linefeed
@@ -261,12 +382,15 @@ logInternal(LogLevel logLevel, const char *fileName, const char *functionName, i
// Determine where to log the message based on log-level-stderr // Determine where to log the message based on log-level-stderr
if (logWillStdErr(logLevel)) if (logWillStdErr(logLevel))
logWrite(logHandleStdErr, logBuffer + messageStdErrPos, bufferPos - messageStdErrPos, "log to stderr"); {
else if (logWillStdOut(logLevel)) if (logRange(logLevelStdErr, logRangeMin, logRangeMax))
logWrite(logHandleStdOut, logBuffer, bufferPos, "log to stdout"); logWriteIndent(logHandleStdErr, logBufferStdErr, indentSize - (size_t)(logBufferStdErr - logBuffer), "log to stderr");
}
else if (logWillStdOut(logLevel) && logRange(logLevelStdOut, logRangeMin, logRangeMax))
logWriteIndent(logHandleStdOut, logBuffer, indentSize, "log to stdout");
// Log to file // Log to file
if (logWillFile(logLevel)) if (logWillFile(logLevel) && logRange(logLevelFile, logRangeMin, logRangeMax))
{ {
// If the banner has not been written // If the banner has not been written
if (!logFileBanner) if (!logFileBanner)
@@ -284,6 +408,8 @@ logInternal(LogLevel logLevel, const char *fileName, const char *functionName, i
logFileBanner = true; logFileBanner = true;
} }
logWrite(logHandleFile, logBuffer, bufferPos, "log to file"); logWriteIndent(logHandleFile, logBuffer, indentSize, "log to file");
} }
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -6,6 +6,13 @@ Log Handler
#include <stdbool.h> #include <stdbool.h>
/***********************************************************************************************************************************
Max size allowed for a single log message including header
***********************************************************************************************************************************/
#ifndef LOG_BUFFER_SIZE
#define LOG_BUFFER_SIZE ((size_t)(32 * 1024))
#endif
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Log types Log types
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -22,6 +29,9 @@ typedef enum
logLevelTrace, logLevelTrace,
} LogLevel; } LogLevel;
#define LOG_LEVEL_MIN logLevelAssert
#define LOG_LEVEL_MAX logLevelTrace
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Expose internal data for unit testing/debugging Expose internal data for unit testing/debugging
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -53,27 +63,37 @@ Macros
Only call logInternal() if the message will be logged to one of the available outputs. Only call logInternal() if the message will be logged to one of the available outputs.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define LOG_ANY(logLevel, code, ...) \ #define LOG_INTERNAL(logLevel, logRangeMin, logRangeMax, code, ...) \
logInternal(logLevel, logRangeMin, logRangeMax, __FILE__, __func__, code, __VA_ARGS__)
#define LOG(logLevel, code, ...) \
LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, LOG_LEVEL_MAX, code, __VA_ARGS__)
#define LOG_WILL(logLevel, code, ...) \
do \
{ \ { \
if (logWill(logLevel)) \ if (logWill(logLevel)) \
logInternal(logLevel, __FILE__, __func__, code, __VA_ARGS__); \ LOG(logLevel, code, __VA_ARGS__); \
} } while(0)
#define LOG_ASSERT(...) \ #define LOG_ASSERT(...) \
LOG_ANY(logLevelAssert, errorTypeCode(&AssertError), __VA_ARGS__) LOG_WILL(logLevelAssert, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR(code, ...) \ #define LOG_ERROR(code, ...) \
LOG_ANY(logLevelError, code, __VA_ARGS__) LOG_WILL(logLevelError, code, __VA_ARGS__)
#define LOG_DEBUG(...) \
LOG_ANY(logLevelDebug, 0, __VA_ARGS__)
#define LOG_INFO(...) \
LOG_ANY(logLevelInfo, 0, __VA_ARGS__)
#define LOG_WARN(...) \ #define LOG_WARN(...) \
LOG_ANY(logLevelWarn, 0, __VA_ARGS__) LOG_WILL(logLevelWarn, 0, __VA_ARGS__)
#define LOG_INFO(...) \
LOG_WILL(logLevelInfo, 0, __VA_ARGS__)
#define LOG_DETAIL(...) \
LOG_WILL(logLevelDetail, 0, __VA_ARGS__)
#define LOG_TRACE(...) \
LOG_WILL(logLevelTrace, 0, __VA_ARGS__)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Internal Functions Internal Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void logInternal( void logInternal(
LogLevel logLevel, const char *fileName, const char *functionName, int code, const char *format, ...); LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, const char *fileName, const char *functionName,
int code, const char *format, ...);
#endif #endif

View File

@@ -5,6 +5,7 @@ Memory Context Manager
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/memContext.h" #include "common/memContext.h"
@@ -64,6 +65,11 @@ Wrapper around malloc()
static void * static void *
memAllocInternal(size_t size, bool zero) memAllocInternal(size_t size, bool zero)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_PARAM(BOOL, zero);
FUNCTION_TEST_END();
// Allocate memory // Allocate memory
void *buffer = malloc(size); void *buffer = malloc(size);
@@ -76,7 +82,7 @@ memAllocInternal(size_t size, bool zero)
memset(buffer, 0, size); memset(buffer, 0, size);
// Return the buffer // Return the buffer
return buffer; FUNCTION_TEST_RESULT(VOIDP, buffer);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -85,6 +91,15 @@ Wrapper around realloc()
static void * static void *
memReAllocInternal(void *bufferOld, size_t sizeOld, size_t sizeNew, bool zeroNew) memReAllocInternal(void *bufferOld, size_t sizeOld, size_t sizeNew, bool zeroNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VOIDP, bufferOld);
FUNCTION_TEST_PARAM(SIZE, sizeOld);
FUNCTION_TEST_PARAM(SIZE, sizeNew);
FUNCTION_TEST_PARAM(BOOL, zeroNew);
FUNCTION_TEST_ASSERT(bufferOld != NULL);
FUNCTION_TEST_END();
// Allocate memory // Allocate memory
void *bufferNew = realloc(bufferOld, sizeNew); void *bufferNew = realloc(bufferOld, sizeNew);
@@ -97,7 +112,7 @@ memReAllocInternal(void *bufferOld, size_t sizeOld, size_t sizeNew, bool zeroNew
memset((unsigned char *)bufferNew + sizeOld, 0, sizeNew - sizeOld); memset((unsigned char *)bufferNew + sizeOld, 0, sizeNew - sizeOld);
// Return the buffer // Return the buffer
return bufferNew; FUNCTION_TEST_RESULT(VOIDP, bufferNew);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -106,12 +121,15 @@ Wrapper around free()
static void static void
memFreeInternal(void *buffer) memFreeInternal(void *buffer)
{ {
// Error if pointer is null FUNCTION_TEST_BEGIN();
if (buffer == NULL) FUNCTION_TEST_PARAM(VOIDP, buffer);
THROW(MemoryError, "unable to free null pointer");
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Free the buffer
free(buffer); free(buffer);
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -120,6 +138,13 @@ Find space for a new mem context
static unsigned int static unsigned int
memContextNewIndex(MemContext *memContext, bool allowFree) memContextNewIndex(MemContext *memContext, bool allowFree)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MEM_CONTEXT, memContext);
FUNCTION_TEST_PARAM(BOOL, allowFree);
FUNCTION_TEST_ASSERT(memContext != NULL);
FUNCTION_TEST_END();
// Try to find space for the new context // Try to find space for the new context
unsigned int contextIdx; unsigned int contextIdx;
@@ -160,7 +185,7 @@ memContextNewIndex(MemContext *memContext, bool allowFree)
} }
} }
return contextIdx; FUNCTION_TEST_RESULT(UINT, contextIdx);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -169,6 +194,12 @@ Create a new memory context
MemContext * MemContext *
memContextNew(const char *name) memContextNew(const char *name)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, name);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_END();
// Check context name length // Check context name length
if (strlen(name) == 0 || strlen(name) > MEM_CONTEXT_NAME_SIZE) if (strlen(name) == 0 || strlen(name) > MEM_CONTEXT_NAME_SIZE)
THROW_FMT(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE); THROW_FMT(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE);
@@ -197,7 +228,7 @@ memContextNew(const char *name)
this->contextParent = memContextCurrent(); this->contextParent = memContextCurrent();
// Return context // Return context
return this; FUNCTION_TEST_RESULT(MEM_CONTEXT, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -206,6 +237,15 @@ Register a callback to be called just before the context is freed
void void
memContextCallback(MemContext *this, void (*callbackFunction)(void *), void *callbackArgument) memContextCallback(MemContext *this, void (*callbackFunction)(void *), void *callbackArgument)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MEM_CONTEXT, this);
FUNCTION_TEST_PARAM(FUNCTIONP, callbackFunction);
FUNCTION_TEST_PARAM(VOIDP, callbackArgument);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(callbackFunction != NULL);
FUNCTION_TEST_END();
// Error if context is not active // Error if context is not active
if (this->state != memContextStateActive) if (this->state != memContextStateActive)
THROW(AssertError, "cannot assign callback to inactive context"); THROW(AssertError, "cannot assign callback to inactive context");
@@ -221,6 +261,8 @@ memContextCallback(MemContext *this, void (*callbackFunction)(void *), void *cal
// Set callback function and argument // Set callback function and argument
this->callbackFunction = callbackFunction; this->callbackFunction = callbackFunction;
this->callbackArgument = callbackArgument; this->callbackArgument = callbackArgument;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -229,6 +271,11 @@ Allocate memory in the memory context and optionally zero it.
static void * static void *
memContextAlloc(size_t size, bool zero) memContextAlloc(size_t size, bool zero)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_PARAM(BOOL, zero);
FUNCTION_TEST_END();
// Find space for the new allocation // Find space for the new allocation
unsigned int allocIdx; unsigned int allocIdx;
@@ -270,7 +317,7 @@ memContextAlloc(size_t size, bool zero)
memContextCurrent()->allocList[allocIdx].buffer = memAllocInternal(size, zero); memContextCurrent()->allocList[allocIdx].buffer = memAllocInternal(size, zero);
// Return buffer // Return buffer
return memContextCurrent()->allocList[allocIdx].buffer; FUNCTION_TEST_RESULT(VOIDP, memContextCurrent()->allocList[allocIdx].buffer);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -279,9 +326,11 @@ Find a memory allocation
static unsigned int static unsigned int
memFind(const void *buffer) memFind(const void *buffer)
{ {
// Error if buffer is null FUNCTION_TEST_BEGIN();
if (buffer == NULL) FUNCTION_TEST_PARAM(VOIDP, buffer);
THROW(AssertError, "unable to find null allocation");
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Find memory allocation // Find memory allocation
unsigned int allocIdx; unsigned int allocIdx;
@@ -294,7 +343,7 @@ memFind(const void *buffer)
if (allocIdx == memContextCurrent()->allocListSize) if (allocIdx == memContextCurrent()->allocListSize)
THROW(AssertError, "unable to find allocation"); THROW(AssertError, "unable to find allocation");
return allocIdx; FUNCTION_TEST_RESULT(UINT, allocIdx);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -303,7 +352,11 @@ Allocate zeroed memory in the memory context
void * void *
memNew(size_t size) memNew(size_t size)
{ {
return memContextAlloc(size, true); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VOIDP, memContextAlloc(size, true));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -312,6 +365,13 @@ Grow allocated memory without initializing the new portion
void * void *
memGrowRaw(const void *buffer, size_t size) memGrowRaw(const void *buffer, size_t size)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VOIDP, buffer);
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Find the allocation // Find the allocation
MemContextAlloc *alloc = &(memContextCurrent()->allocList[memFind(buffer)]); MemContextAlloc *alloc = &(memContextCurrent()->allocList[memFind(buffer)]);
@@ -319,7 +379,7 @@ memGrowRaw(const void *buffer, size_t size)
alloc->buffer = memReAllocInternal(alloc->buffer, alloc->size, size, false); alloc->buffer = memReAllocInternal(alloc->buffer, alloc->size, size, false);
alloc->size = (unsigned int)size; alloc->size = (unsigned int)size;
return alloc->buffer; FUNCTION_TEST_RESULT(VOIDP, alloc->buffer);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -328,7 +388,11 @@ Allocate memory in the memory context without initializing it
void * void *
memNewRaw(size_t size) memNewRaw(size_t size)
{ {
return memContextAlloc(size, false); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VOIDP, memContextAlloc(size, false));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -337,12 +401,20 @@ Free a memory allocation in the context
void void
memFree(void *buffer) memFree(void *buffer)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VOIDP, buffer);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Find the allocation // Find the allocation
MemContextAlloc *alloc = &(memContextCurrent()->allocList[memFind(buffer)]); MemContextAlloc *alloc = &(memContextCurrent()->allocList[memFind(buffer)]);
// Free the buffer // Free the buffer
memFreeInternal(alloc->buffer); memFreeInternal(alloc->buffer);
alloc->active = false; alloc->active = false;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -353,6 +425,13 @@ This is generally used to move objects to a new context once they have been succ
void void
memContextMove(MemContext *this, MemContext *parentNew) memContextMove(MemContext *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MEM_CONTEXT, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
// Only move if a valid mem context is provided // Only move if a valid mem context is provided
if (this != NULL) if (this != NULL)
{ {
@@ -382,6 +461,8 @@ memContextMove(MemContext *this, MemContext *parentNew)
// Assign new parent // Assign new parent
this->contextParent = parentNew; this->contextParent = parentNew;
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -390,6 +471,12 @@ Switch to the specified context and return the old context
MemContext * MemContext *
memContextSwitch(MemContext *this) memContextSwitch(MemContext *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MEM_CONTEXT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// Error if context is not active // Error if context is not active
if (this->state != memContextStateActive) if (this->state != memContextStateActive)
THROW(AssertError, "cannot switch to inactive context"); THROW(AssertError, "cannot switch to inactive context");
@@ -397,7 +484,7 @@ memContextSwitch(MemContext *this)
MemContext *memContextOld = memContextCurrent(); MemContext *memContextOld = memContextCurrent();
contextCurrent = this; contextCurrent = this;
return memContextOld; FUNCTION_TEST_RESULT(MEM_CONTEXT, memContextOld);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -406,7 +493,8 @@ Return the top context
MemContext * MemContext *
memContextTop() memContextTop()
{ {
return &contextTop; FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(MEM_CONTEXT, &contextTop);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -415,7 +503,8 @@ Return the current context
MemContext * MemContext *
memContextCurrent() memContextCurrent()
{ {
return contextCurrent; FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(MEM_CONTEXT, contextCurrent);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -424,11 +513,17 @@ Return the context name
const char * const char *
memContextName(MemContext *this) memContextName(MemContext *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MEM_CONTEXT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// Error if context is not active // Error if context is not active
if (this->state != memContextStateActive) if (this->state != memContextStateActive)
THROW(AssertError, "cannot get name for inactive context"); THROW(AssertError, "cannot get name for inactive context");
return this->name; FUNCTION_TEST_RESULT(STRINGZ, this->name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -437,10 +532,15 @@ memContextFree - free all memory used by the context and all child contexts
void void
memContextFree(MemContext *this) memContextFree(MemContext *this)
{ {
// If context is already freeing then return if memContextFree() is called again - this can happen in callbacks FUNCTION_TEST_BEGIN();
if (this->state == memContextStateFreeing) FUNCTION_TEST_PARAM(MEM_CONTEXT, this);
return;
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// If context is already freeing then return if memContextFree() is called again - this can happen in callbacks
if (this->state != memContextStateFreeing)
{
// Current context cannot be freed unless it is top (top is never really freed, just the stuff under it) // Current context cannot be freed unless it is top (top is never really freed, just the stuff under it)
if (this == memContextCurrent() && this != memContextTop()) if (this == memContextCurrent() && this != memContextTop())
THROW_FMT(AssertError, "cannot free current context '%s'", this->name); THROW_FMT(AssertError, "cannot free current context '%s'", this->name);
@@ -496,3 +596,6 @@ memContextFree(MemContext *this)
else else
memset(this, 0, sizeof(MemContext)); memset(this, 0, sizeof(MemContext));
} }
FUNCTION_TEST_RESULT_VOID();
}

View File

@@ -188,4 +188,12 @@ MEM_CONTEXT_TEMP_END();
} \ } \
} }
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_MEM_CONTEXT_TYPE \
MemContext *
#define FUNCTION_DEBUG_MEM_CONTEXT_FORMAT(value, buffer, bufferSize) \
objToLog(value, "MemContext", buffer, bufferSize)
#endif #endif

View File

@@ -4,6 +4,7 @@ Regular Expression Handler
#include <regex.h> #include <regex.h>
#include <sys/types.h> #include <sys/types.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/regExp.h" #include "common/regExp.h"
@@ -22,9 +23,15 @@ Handle errors
static void static void
regExpError(int error) regExpError(int error)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, error);
FUNCTION_TEST_END();
char buffer[4096]; char buffer[4096];
regerror(error, NULL, buffer, sizeof(buffer)); regerror(error, NULL, buffer, sizeof(buffer));
THROW(FormatError, buffer); THROW(FormatError, buffer);
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -33,6 +40,12 @@ New regular expression handler
RegExp * RegExp *
regExpNew(const String *expression) regExpNew(const String *expression)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, expression);
FUNCTION_TEST_ASSERT(expression != NULL);
FUNCTION_TEST_END();
RegExp *this = NULL; RegExp *this = NULL;
MEM_CONTEXT_NEW_BEGIN("RegExp") MEM_CONTEXT_NEW_BEGIN("RegExp")
@@ -54,7 +67,7 @@ regExpNew(const String *expression)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_TEST_RESULT(REGEXP, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -63,6 +76,14 @@ Match on a regular expression
bool bool
regExpMatch(RegExp *this, const String *string) regExpMatch(RegExp *this, const String *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(REGEXP, this);
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_END();
// Test for a match // Test for a match
int result = regexec(&this->regExp, strPtr(string), 0, NULL, 0); int result = regexec(&this->regExp, strPtr(string), 0, NULL, 0);
@@ -70,7 +91,7 @@ regExpMatch(RegExp *this, const String *string)
if (result != 0 && result != REG_NOMATCH) // {uncoverable - no error condition known} if (result != 0 && result != REG_NOMATCH) // {uncoverable - no error condition known}
regExpError(result); // {+uncoverable} regExpError(result); // {+uncoverable}
return result == 0; FUNCTION_TEST_RESULT(BOOL, result == 0);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -79,11 +100,17 @@ Free regular expression
void void
regExpFree(RegExp *this) regExpFree(RegExp *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(REGEXP, this);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
{ {
regfree(&this->regExp); regfree(&this->regExp);
memContextFree(this->memContext); memContextFree(this->memContext);
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -92,6 +119,14 @@ Match a regular expression in one call for brevity
bool bool
regExpMatchOne(const String *expression, const String *string) regExpMatchOne(const String *expression, const String *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, expression);
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(expression != NULL);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
RegExp *regExp = regExpNew(expression); RegExp *regExp = regExpNew(expression);
@@ -105,5 +140,5 @@ regExpMatchOne(const String *expression, const String *string)
} }
TRY_END(); TRY_END();
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }

View File

@@ -20,4 +20,12 @@ void regExpFree(RegExp *this);
bool regExpMatchOne(const String *expression, const String *string); bool regExpMatchOne(const String *expression, const String *string);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_REGEXP_TYPE \
RegExp *
#define FUNCTION_DEBUG_REGEXP_FORMAT(value, buffer, bufferSize) \
objToLog(value, "RegExp", buffer, bufferSize)
#endif #endif

363
src/common/stackTrace.c Normal file
View File

@@ -0,0 +1,363 @@
/***********************************************************************************************************************************
Stack Trace Handler
***********************************************************************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BACKTRACE
#include <backtrace.h>
#include <backtrace-supported.h>
#endif
#include "common/assert.h"
#include "common/error.h"
#include "common/log.h"
#include "common/stackTrace.h"
/***********************************************************************************************************************************
Max call stack depth
***********************************************************************************************************************************/
#define STACK_TRACE_MAX 128
/***********************************************************************************************************************************
Track stack trace
***********************************************************************************************************************************/
static int stackSize = 0;
typedef struct StackTraceData
{
const char *fileName;
const char *functionName;
unsigned int fileLine;
LogLevel functionLogLevel;
unsigned int tryDepth;
char *param;
size_t paramSize;
bool paramOverflow;
bool paramLog;
} StackTraceData;
static StackTraceData stackTrace[STACK_TRACE_MAX];
/***********************************************************************************************************************************
Buffer to hold function parameters
***********************************************************************************************************************************/
static char functionParamBuffer[32 * 1024];
struct backtrace_state *backTraceState = NULL;
/***********************************************************************************************************************************
Backtrace init and callbacks
***********************************************************************************************************************************/
#ifdef WITH_BACKTRACE
void
stackTraceInit(const char *exe)
{
if (backTraceState == NULL)
backTraceState = backtrace_create_state(exe, false, NULL, NULL);
}
static int
backTraceCallback(void *data, uintptr_t pc, const char *filename, int lineno, const char *function)
{
(void)(data);
(void)(pc);
(void)(filename);
(void)(function);
if (stackSize > 0)
stackTrace[stackSize - 1].fileLine = (unsigned int)lineno;
return 1;
}
static void
backTraceCallbackError(void *data, const char *msg, int errnum)
{
(void)data;
(void)msg;
(void)errnum;
}
#endif
/***********************************************************************************************************************************
Flag to enable/disable test function logging
***********************************************************************************************************************************/
#ifndef NDEBUG
bool stackTraceTestFlag = true;
void
stackTraceTestStart()
{
stackTraceTestFlag = true;
}
void
stackTraceTestStop()
{
stackTraceTestFlag = false;
}
bool
stackTraceTest()
{
return stackTraceTestFlag;
}
#endif
/***********************************************************************************************************************************
Push a new function onto the trace stack
***********************************************************************************************************************************/
LogLevel
stackTracePush(const char *fileName, const char *functionName, LogLevel functionLogLevel)
{
ASSERT(stackSize < STACK_TRACE_MAX - 1);
// Get line number from backtrace if available
#ifdef WITH_BACKTRACE
backtrace_full(backTraceState, 2, backTraceCallback, backTraceCallbackError, NULL);
#endif
// This struct could be holding old trace data so init to zero
StackTraceData *data = &stackTrace[stackSize];
memset(data, 0, sizeof(StackTraceData));
// Set function info
data->fileName = fileName;
data->functionName = functionName;
data->tryDepth = errorTryDepth();
// Set param pointer
if (stackSize == 0)
{
data->param = functionParamBuffer;
data->functionLogLevel = functionLogLevel;
}
else
{
StackTraceData *dataPrior = &stackTrace[stackSize - 1];
data->param = dataPrior->param + dataPrior->paramSize + 1;
// Log level cannot be lower than the prior function
if (functionLogLevel < dataPrior->functionLogLevel)
data->functionLogLevel = dataPrior->functionLogLevel;
else
data->functionLogLevel = functionLogLevel;
}
stackSize++;
return data->functionLogLevel;
}
/***********************************************************************************************************************************
Get parameters for the top function on the stack
***********************************************************************************************************************************/
static const char *
stackTraceParamIdx(int stackIdx)
{
ASSERT_DEBUG(stackSize > 0);
ASSERT_DEBUG(stackIdx < stackSize);
StackTraceData *data = &stackTrace[stackIdx];
if (data->paramLog)
{
if (data->paramOverflow)
return "!!! buffer overflow - parameters not available !!!";
if (data->paramSize == 0)
return "void";
return data->param;
}
return "debug log level required for parameters";
}
const char *
stackTraceParam()
{
return stackTraceParamIdx(stackSize - 1);
}
/***********************************************************************************************************************************
Get the next location where a parameter can be added in the param buffer
***********************************************************************************************************************************/
char *
stackTraceParamBuffer(const char *paramName)
{
ASSERT_DEBUG(stackSize > 0);
StackTraceData *data = &stackTrace[stackSize - 1];
size_t paramNameSize = strlen(paramName);
// Make sure that adding this parameter will not overflow the buffer
if ((size_t)(data->param - functionParamBuffer) + data->paramSize + paramNameSize + 4 >
sizeof(functionParamBuffer) - (STACK_TRACE_PARAM_MAX * 2))
{
// Set overflow to true
data->paramOverflow = true;
// There's no way to stop the parameter from being formatted so we reserve a space at the end where the format can safely
// take place and not disturb the rest of the buffer. Hopefully overflows just won't happen but we need to be prepared in
// case of runaway recursion or some other issue that fills the buffer because we don't want a segfault.
return functionParamBuffer + sizeof(functionParamBuffer) - STACK_TRACE_PARAM_MAX;
}
// Add a comma if a parameter is already in the list
if (data->paramSize != 0)
{
data->param[data->paramSize++] = ',';
data->param[data->paramSize++] = ' ';
}
// Add the parameter name
strcpy(data->param + data->paramSize, paramName);
data->paramSize += paramNameSize;
// Add param/value separator
data->param[data->paramSize++] = ':';
data->param[data->paramSize++] = ' ';
return data->param + data->paramSize;
}
/***********************************************************************************************************************************
Add a parameter to the function on the top of the stack
***********************************************************************************************************************************/
void
stackTraceParamAdd(size_t bufferSize)
{
ASSERT_DEBUG(stackSize > 0);
StackTraceData *data = &stackTrace[stackSize - 1];
if (!data->paramOverflow)
data->paramSize += bufferSize;
}
/***********************************************************************************************************************************
Mark that parameters are being logged -- it none appear then the function is void
***********************************************************************************************************************************/
void
stackTraceParamLog()
{
ASSERT_DEBUG(stackSize > 0);
stackTrace[stackSize - 1].paramLog = true;
}
/***********************************************************************************************************************************
Pop a function from the stack trace
***********************************************************************************************************************************/
#ifdef NDEBUG
void
stackTracePop()
{
stackSize--;
}
#else
void
stackTracePop(const char *fileName, const char *functionName)
{
ASSERT_DEBUG(stackSize > 0);
stackSize--;
StackTraceData *data = &stackTrace[stackSize];
if (strcmp(data->fileName, fileName) != 0 || strcmp(data->functionName, functionName) != 0)
THROW_FMT(AssertError, "popping %s:%s but expected %s:%s", fileName, functionName, data->fileName, data->functionName);
}
#endif
/***********************************************************************************************************************************
Stack trace format
***********************************************************************************************************************************/
static size_t
stackTraceFmt(char *buffer, size_t bufferSize, size_t bufferUsed, const char *format, ...)
{
va_list argumentList;
va_start(argumentList, format);
int result = vsnprintf(
buffer + bufferUsed, bufferUsed < bufferSize ? bufferSize - bufferUsed : 0, format, argumentList);
va_end(argumentList);
return (size_t)result;
}
/***********************************************************************************************************************************
Generate the stack trace
***********************************************************************************************************************************/
size_t
stackTraceToZ(char *buffer, size_t bufferSize, const char *fileName, const char *functionName, unsigned int fileLine)
{
size_t result = 0;
const char *param = "test build required for parameters";
int stackIdx = stackSize - 1;
// If the current function passed in is the same as the top function on the stack then use the parameters for that function
if (stackSize > 0 && strcmp(fileName, stackTrace[stackIdx].fileName) == 0 &&
strcmp(functionName, stackTrace[stackIdx].functionName) == 0)
{
param = stackTraceParamIdx(stackSize - 1);
stackIdx--;
}
// Output the current function
result = stackTraceFmt(
buffer, bufferSize, 0, "%.*s:%s:%u:(%s)", (int)(strlen(fileName) - 2), fileName, functionName, fileLine, param);
// Output stack if there is anything on it
if (stackIdx >= 0)
{
// If the function passed in was not at the top of the stack then some functions are missing
if (stackIdx == stackSize - 1)
result += stackTraceFmt(buffer, bufferSize, result, "\n ... function(s) ommitted ...");
// Output the rest of the stack
for (; stackIdx >= 0; stackIdx--)
{
StackTraceData *data = &stackTrace[stackIdx];
result += stackTraceFmt(
buffer, bufferSize, result, "\n%.*s:%s"
#ifdef WITH_BACKTRACE
":%u"
#endif
":(%s)", (int)(strlen(data->fileName) - 2), data->fileName, data->functionName,
#ifdef WITH_BACKTRACE
data->fileLine,
#endif
stackTraceParamIdx(stackIdx));
}
}
return result;
}
/***********************************************************************************************************************************
Clean the stack at and below the try level
Called by the error to cleanup the stack when an exception occurs.
***********************************************************************************************************************************/
void
stackTraceClean(unsigned int tryDepth)
{
while (stackSize > 0 && stackTrace[stackSize - 1].tryDepth >= tryDepth)
stackSize--;
}

59
src/common/stackTrace.h Normal file
View File

@@ -0,0 +1,59 @@
/***********************************************************************************************************************************
Stack Trace Handler
***********************************************************************************************************************************/
#ifndef COMMON_STACKTRACE_H
#define COMMON_STACKTRACE_H
#include <sys/types.h>
#include "common/log.h"
/***********************************************************************************************************************************
Maximum size of a single parameter (including NULL terminator)
***********************************************************************************************************************************/
#define STACK_TRACE_PARAM_MAX 256
/***********************************************************************************************************************************
Macros to access internal functions
***********************************************************************************************************************************/
#define STACK_TRACE_PUSH(logLevel) \
stackTracePush(__FILE__, __func__, logLevel)
#ifdef NDEBUG
#define STACK_TRACE_POP() \
stackTracePop();
#else
#define STACK_TRACE_POP() \
stackTracePop(__FILE__, __func__);
#endif
/***********************************************************************************************************************************
Internal Functions
***********************************************************************************************************************************/
#ifdef WITH_BACKTRACE
void stackTraceInit(const char *exe);
#endif
#ifndef NDEBUG
void stackTraceTestStart();
void stackTraceTestStop();
bool stackTraceTest();
#endif
LogLevel stackTracePush(const char *fileName, const char *functionName, LogLevel functionLogLevel);
#ifdef NDEBUG
void stackTracePop();
#else
void stackTracePop(const char *fileName, const char *functionName);
#endif
size_t stackTraceToZ(char *buffer, size_t bufferSize, const char *fileName, const char *functionName, unsigned int fileLine);
void stackTraceParamLog();
const char *stackTraceParam();
char *stackTraceParamBuffer(const char *param);
void stackTraceParamAdd(size_t bufferSize);
void stackTraceClean(unsigned int tryDepth);
#endif

View File

@@ -4,6 +4,7 @@ Time Management
#include "stdio.h" #include "stdio.h"
#include "sys/time.h" #include "sys/time.h"
#include "common/debug.h"
#include "common/time.h" #include "common/time.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -17,9 +18,12 @@ Epoch time in milliseconds
TimeMSec TimeMSec
timeMSec() timeMSec()
{ {
FUNCTION_TEST_VOID();
struct timeval currentTime; struct timeval currentTime;
gettimeofday(&currentTime, NULL); gettimeofday(&currentTime, NULL);
return ((TimeMSec)currentTime.tv_sec * MSEC_PER_SEC) + (TimeMSec)currentTime.tv_usec / MSEC_PER_USEC;
FUNCTION_TEST_RESULT(UINT64, ((TimeMSec)currentTime.tv_sec * MSEC_PER_SEC) + (TimeMSec)currentTime.tv_usec / MSEC_PER_USEC);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -28,8 +32,14 @@ Sleep for specified milliseconds
void void
sleepMSec(TimeMSec sleepMSec) sleepMSec(TimeMSec sleepMSec)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT64, sleepMSec);
FUNCTION_TEST_END();
struct timeval delay; struct timeval delay;
delay.tv_sec = (time_t)(sleepMSec / MSEC_PER_SEC); delay.tv_sec = (time_t)(sleepMSec / MSEC_PER_SEC);
delay.tv_usec = (time_t)(sleepMSec % MSEC_PER_SEC * 1000); delay.tv_usec = (time_t)(sleepMSec % MSEC_PER_SEC * 1000);
select(0, NULL, NULL, NULL, &delay); select(0, NULL, NULL, NULL, &delay);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -1,9 +1,11 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
String Handler String Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <stdio.h>
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/type/buffer.h" #include "common/type/buffer.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -22,6 +24,10 @@ Create a new buffer
Buffer * Buffer *
bufNew(size_t size) bufNew(size_t size)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_END();
Buffer *this = NULL; Buffer *this = NULL;
MEM_CONTEXT_NEW_BEGIN("Buffer") MEM_CONTEXT_NEW_BEGIN("Buffer")
@@ -37,7 +43,7 @@ bufNew(size_t size)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -46,13 +52,18 @@ Create a new buffer from a C buffer
Buffer * Buffer *
bufNewC(size_t size, const void *buffer) bufNewC(size_t size, const void *buffer)
{ {
// Create object FUNCTION_TEST_BEGIN();
Buffer *this = bufNew(size); FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_PARAM(VOIDP, buffer);
// Copy the data FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Create object and copy data
Buffer *this = bufNew(size);
memcpy(this->buffer, buffer, this->size); memcpy(this->buffer, buffer, this->size);
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -61,13 +72,19 @@ Create a new buffer from a string
Buffer * Buffer *
bufNewStr(const String *string) bufNewStr(const String *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_END();
// Create object // Create object
Buffer *this = bufNew(strSize(string)); Buffer *this = bufNew(strSize(string));
// Copy the data // Copy the data
memcpy(this->buffer, strPtr(string), this->size); memcpy(this->buffer, strPtr(string), this->size);
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -76,7 +93,12 @@ Append the contents of another buffer
Buffer * Buffer *
bufCat(Buffer *this, const Buffer *cat) bufCat(Buffer *this, const Buffer *cat)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(BUFFER, cat);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (cat != NULL && cat->size > 0) if (cat != NULL && cat->size > 0)
{ {
@@ -86,7 +108,7 @@ bufCat(Buffer *this, const Buffer *cat)
memcpy(this->buffer + sizeOld, cat->buffer, cat->size); memcpy(this->buffer + sizeOld, cat->buffer, cat->size);
} }
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -95,15 +117,20 @@ Are two buffers equal?
bool bool
bufEq(const Buffer *this, const Buffer *compare) bufEq(const Buffer *this, const Buffer *compare)
{ {
bool result = false; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(BUFFER, compare);
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_ASSERT(this != NULL);
ASSERT_DEBUG(compare != NULL); FUNCTION_TEST_ASSERT(compare != NULL);
FUNCTION_TEST_END();
bool result = false;
if (this->size == compare->size) if (this->size == compare->size)
result = memcmp(this->buffer, compare->buffer, compare->size) == 0; result = memcmp(this->buffer, compare->buffer, compare->size) == 0;
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -112,10 +139,17 @@ Move buffer to a new mem context
Buffer * Buffer *
bufMove(Buffer *this, MemContext *parentNew) bufMove(Buffer *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextMove(this->memContext, parentNew); memContextMove(this->memContext, parentNew);
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -124,7 +158,13 @@ Return buffer ptr
unsigned char * unsigned char *
bufPtr(const Buffer *this) bufPtr(const Buffer *this)
{ {
return this->buffer; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UCHARP, this->buffer);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -133,6 +173,13 @@ Resize the buffer
Buffer * Buffer *
bufResize(Buffer *this, size_t size) bufResize(Buffer *this, size_t size)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// Only resize if it the new size is different // Only resize if it the new size is different
if (this->size != size) if (this->size != size)
{ {
@@ -167,7 +214,7 @@ bufResize(Buffer *this, size_t size)
} }
} }
return this; FUNCTION_TEST_RESULT(BUFFER, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -176,7 +223,37 @@ Return buffer size
size_t size_t
bufSize(const Buffer *this) bufSize(const Buffer *this)
{ {
return this->size; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
}
/***********************************************************************************************************************************
Convert to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
bufToLog(const Buffer *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
string = strNew("null");
else
string = strNewFmt("{size: %zu}", this->size);
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
MEM_CONTEXT_TEMP_END();
return result;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -185,6 +262,12 @@ Free the buffer
void void
bufFree(Buffer *this) bufFree(Buffer *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -26,4 +26,14 @@ size_t bufSize(const Buffer *this);
unsigned char *bufPtr(const Buffer *this); unsigned char *bufPtr(const Buffer *this);
void bufFree(Buffer *this); void bufFree(Buffer *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t bufToLog(const Buffer *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_BUFFER_TYPE \
Buffer *
#define FUNCTION_DEBUG_BUFFER_FORMAT(value, buffer, bufferSize) \
bufToLog(value, buffer, bufferSize)
#endif #endif

266
src/common/type/convert.c Normal file
View File

@@ -0,0 +1,266 @@
/***********************************************************************************************************************************
Convert Base Data Types
***********************************************************************************************************************************/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/assert.h"
#include "common/debug.h"
#include "common/type/convert.h"
/***********************************************************************************************************************************
Convert uint64 to zero-terminated string
***********************************************************************************************************************************/
size_t
cvtBoolToZ(bool value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BOOL, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%s", value ? "true" : "false");
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
/***********************************************************************************************************************************
Convert double to zero-terminated string and vice versa
***********************************************************************************************************************************/
size_t
cvtDoubleToZ(double value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(DOUBLE, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Convert to a string
size_t result = (size_t)snprintf(buffer, bufferSize, "%lf", value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
// Any formatted double should be at least 8 characters, i.e. 0.000000
ASSERT_DEBUG(strlen(buffer) >= 8);
// Any formatted double should have a decimal point
ASSERT_DEBUG(strchr(buffer, '.') != NULL);
// Strip off any final 0s and the decimal point if there are no non-zero digits after it
char *end = buffer + strlen(buffer) - 1;
while (*end == '0' || *end == '.')
{
// It should not be possible to go past the beginning because format "%lf" will always write a decimal point
ASSERT_DEBUG(end > buffer);
end--;
if (*(end + 1) == '.')
break;
}
// Zero terminate the string
end[1] = 0;
// Return string length
FUNCTION_TEST_RESULT(SIZE, (size_t)(end - buffer + 1));
}
double
cvtZToDouble(const char *value)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, value);
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
double result = 0;
sscanf(value, "%lf", &result);
if (result == 0 && strcmp(value, "0") != 0)
THROW_FMT(FormatError, "unable to convert string '%s' to double", value);
FUNCTION_TEST_RESULT(DOUBLE, result);
}
/***********************************************************************************************************************************
Convert int to zero-terminated string and vice versa
***********************************************************************************************************************************/
size_t
cvtIntToZ(int value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%d", value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
int
cvtZToInt(const char *value)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, value);
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
int result = atoi(value);
if (result == 0 && strcmp(value, "0") != 0)
THROW_FMT(FormatError, "unable to convert string '%s' to int", value);
FUNCTION_TEST_RESULT(INT, result);
}
/***********************************************************************************************************************************
Convert int64 to zero-terminated string and vice versa
***********************************************************************************************************************************/
size_t
cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT64, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%" PRId64, value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
int64_t
cvtZToInt64(const char *value)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, value);
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
int64_t result = atoll(value);
char buffer[32];
snprintf(buffer, sizeof(buffer), "%" PRId64, result);
if (strcmp(value, buffer) != 0)
THROW_FMT(FormatError, "unable to convert string '%s' to int64", value);
FUNCTION_TEST_RESULT(INT64, result);
}
/***********************************************************************************************************************************
Convert mode to zero-terminated string
***********************************************************************************************************************************/
size_t
cvtModeToZ(mode_t value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(MODE, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%04o", value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
/***********************************************************************************************************************************
Convert size to zero-terminated string
***********************************************************************************************************************************/
size_t
cvtSizeToZ(size_t value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%zu", value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
/***********************************************************************************************************************************
Convert uint to zero-terminated string
***********************************************************************************************************************************/
size_t
cvtUIntToZ(unsigned int value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%u", value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}
/***********************************************************************************************************************************
Convert uint64 to zero-terminated string
***********************************************************************************************************************************/
size_t
cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT64, value);
FUNCTION_TEST_PARAM(CHARP, buffer);
FUNCTION_TEST_PARAM(SIZE, bufferSize);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
size_t result = (size_t)snprintf(buffer, bufferSize, "%" PRIu64, value);
if (result >= bufferSize)
THROW(AssertError, "buffer overflow");
FUNCTION_TEST_RESULT(SIZE, result);
}

32
src/common/type/convert.h Normal file
View File

@@ -0,0 +1,32 @@
/***********************************************************************************************************************************
Convert Base Data Types
***********************************************************************************************************************************/
#ifndef COMMON_TYPE_CONVERT_H
#define COMMON_TYPE_CONVERT_H
#include <inttypes.h>
#include <sys/types.h>
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
size_t cvtDoubleToZ(double value, char *buffer, size_t bufferSize);
double cvtZToDouble(const char *value);
size_t cvtIntToZ(int value, char *buffer, size_t bufferSize);
int cvtZToInt(const char *value);
size_t cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize);
int64_t cvtZToInt64(const char *value);
size_t cvtModeToZ(mode_t value, char *buffer, size_t bufferSize);
size_t cvtSizeToZ(size_t value, char *buffer, size_t bufferSize);
size_t cvtUIntToZ(unsigned int value, char *buffer, size_t bufferSize);
size_t cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize);
size_t cvtBoolToZ(bool value, char *buffer, size_t bufferSize);
#endif

View File

@@ -3,6 +3,7 @@ Key Value Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <limits.h> #include <limits.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/type/keyValue.h" #include "common/type/keyValue.h"
#include "common/type/list.h" #include "common/type/list.h"
@@ -38,9 +39,11 @@ Create a new key/value store
KeyValue * KeyValue *
kvNew() kvNew()
{ {
FUNCTION_TEST_VOID();
KeyValue *this = NULL; KeyValue *this = NULL;
MEM_CONTEXT_NEW_BEGIN("keyValue") MEM_CONTEXT_NEW_BEGIN("KeyValue")
{ {
// Allocate state and set context // Allocate state and set context
this = memNew(sizeof(KeyValue)); this = memNew(sizeof(KeyValue));
@@ -52,7 +55,7 @@ kvNew()
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_TEST_RESULT(KEY_VALUE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -61,6 +64,12 @@ Duplicate key/value store
KeyValue * KeyValue *
kvDup(const KeyValue *source) kvDup(const KeyValue *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, source);
FUNCTION_TEST_ASSERT(source != NULL);
FUNCTION_TEST_END();
KeyValue *this = kvNew(); KeyValue *this = kvNew();
// Duplicate all key/values // Duplicate all key/values
@@ -79,7 +88,7 @@ kvDup(const KeyValue *source)
this->keyList = varLstDup(source->keyList); this->keyList = varLstDup(source->keyList);
return this; FUNCTION_TEST_RESULT(KEY_VALUE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -88,23 +97,30 @@ Get key index if it exists
static unsigned int static unsigned int
kvGetIdx(const KeyValue *this, const Variant *key) kvGetIdx(const KeyValue *this, const Variant *key)
{ {
// Search for the key FUNCTION_TEST_BEGIN();
unsigned int listIdx = 0; FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
for (; listIdx < lstSize(this->list); listIdx++) FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
// Search for the key
unsigned int result = KEY_NOT_FOUND;
for (unsigned int listIdx = 0; listIdx < lstSize(this->list); listIdx++)
{ {
const KeyValuePair *pair = (const KeyValuePair *)lstGet(this->list, listIdx); const KeyValuePair *pair = (const KeyValuePair *)lstGet(this->list, listIdx);
// Break if the key matches // Break if the key matches
if (varEq(key, pair->key)) if (varEq(key, pair->key))
{
result = listIdx;
break; break;
} }
}
// If key was not found FUNCTION_TEST_RESULT(UINT, result);
if (listIdx == lstSize(this->list))
return KEY_NOT_FOUND;
return listIdx;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -113,7 +129,13 @@ Get list of keys
const VariantList * const VariantList *
kvKeyList(const KeyValue *this) kvKeyList(const KeyValue *this)
{ {
return this->keyList; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT_LIST, this->keyList);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -124,6 +146,15 @@ Handles the common logic for the external put functions. The correct mem context
static void static void
kvPutInternal(KeyValue *this, const Variant *key, Variant *value) kvPutInternal(KeyValue *this, const Variant *key, Variant *value)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_PARAM(VARIANT, value);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
// Find the key // Find the key
unsigned int listIdx = kvGetIdx(this, key); unsigned int listIdx = kvGetIdx(this, key);
@@ -151,6 +182,8 @@ kvPutInternal(KeyValue *this, const Variant *key, Variant *value)
pair->value = value; pair->value = value;
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -159,13 +192,22 @@ Put key/value pair
KeyValue * KeyValue *
kvPut(KeyValue *this, const Variant *key, const Variant *value) kvPut(KeyValue *this, const Variant *key, const Variant *value)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_PARAM(VARIANT, value);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
{ {
kvPutInternal(this, key, varDup(value)); kvPutInternal(this, key, varDup(value));
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(KEY_VALUE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -174,6 +216,15 @@ Add value to key -- if the key does not exist then this works the same as kvPut(
KeyValue * KeyValue *
kvAdd(KeyValue *this, const Variant *key, const Variant *value) kvAdd(KeyValue *this, const Variant *key, const Variant *value)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_PARAM(VARIANT, value);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
{ {
// Find the key // Find the key
@@ -193,7 +244,7 @@ kvAdd(KeyValue *this, const Variant *key, const Variant *value)
pair->value = varDup(value); pair->value = varDup(value);
else if (varType(pair->value) != varTypeVariantList) else if (varType(pair->value) != varTypeVariantList)
{ {
Variant *valueList = varNewVarLstEmpty(); Variant *valueList = varNewVarLst(varLstNew());
varLstAdd(varVarLst(valueList), pair->value); varLstAdd(varVarLst(valueList), pair->value);
varLstAdd(varVarLst(valueList), varDup(value)); varLstAdd(varVarLst(valueList), varDup(value));
pair->value = valueList; pair->value = valueList;
@@ -204,7 +255,7 @@ kvAdd(KeyValue *this, const Variant *key, const Variant *value)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(KEY_VALUE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -216,6 +267,14 @@ key/value store.
KeyValue * KeyValue *
kvPutKv(KeyValue *this, const Variant *key) kvPutKv(KeyValue *this, const Variant *key)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
KeyValue *result = NULL; KeyValue *result = NULL;
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
@@ -227,7 +286,7 @@ kvPutKv(KeyValue *this, const Variant *key)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return result; FUNCTION_TEST_RESULT(KEY_VALUE, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -236,6 +295,14 @@ Get a value using the key
const Variant * const Variant *
kvGet(const KeyValue *this, const Variant *key) kvGet(const KeyValue *this, const Variant *key)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
Variant *result = NULL; Variant *result = NULL;
// Find the key // Find the key
@@ -244,7 +311,7 @@ kvGet(const KeyValue *this, const Variant *key)
if (listIdx != KEY_NOT_FOUND) if (listIdx != KEY_NOT_FOUND)
result = ((KeyValuePair *)lstGet(this->list, listIdx))->value; result = ((KeyValuePair *)lstGet(this->list, listIdx))->value;
return result; FUNCTION_TEST_RESULT(VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -253,6 +320,14 @@ Get a value as a list (even if there is only one value) using the key
VariantList * VariantList *
kvGetList(const KeyValue *this, const Variant *key) kvGetList(const KeyValue *this, const Variant *key)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_PARAM(VARIANT, key);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(key != NULL);
FUNCTION_TEST_END();
VariantList *result = NULL; VariantList *result = NULL;
// Get the value // Get the value
@@ -264,7 +339,7 @@ kvGetList(const KeyValue *this, const Variant *key)
else else
result = varLstAdd(varLstNew(), varDup(value)); result = varLstAdd(varLstNew(), varDup(value));
return result; FUNCTION_TEST_RESULT(VARIANT_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -273,5 +348,12 @@ Free the string
void void
kvFree(KeyValue *this) kvFree(KeyValue *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(KEY_VALUE, this);
FUNCTION_TEST_END();
if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -24,4 +24,12 @@ const Variant *kvGet(const KeyValue *this, const Variant *key);
VariantList *kvGetList(const KeyValue *this, const Variant *key); VariantList *kvGetList(const KeyValue *this, const Variant *key);
void kvFree(KeyValue *this); void kvFree(KeyValue *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_KEY_VALUE_TYPE \
KeyValue *
#define FUNCTION_DEBUG_KEY_VALUE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "KeyValue", buffer, bufferSize)
#endif #endif

View File

@@ -2,9 +2,11 @@
List Handler List Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "common/debug.h"
#include "common/type/list.h" #include "common/type/list.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -25,6 +27,8 @@ Create a new list
List * List *
lstNew(size_t itemSize) lstNew(size_t itemSize)
{ {
FUNCTION_TEST_VOID();
List *this = NULL; List *this = NULL;
MEM_CONTEXT_NEW_BEGIN("List") MEM_CONTEXT_NEW_BEGIN("List")
@@ -36,8 +40,7 @@ lstNew(size_t itemSize)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
// Return buffer FUNCTION_TEST_RESULT(LIST, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -46,6 +49,14 @@ Add an item to the end of the list
List * List *
lstAdd(List *this, const void *item) lstAdd(List *this, const void *item)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_PARAM(VOIDP, item);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(item != NULL);
FUNCTION_TEST_END();
// If list size = max then allocate more space // If list size = max then allocate more space
if (this->listSize == this->listSizeMax) if (this->listSize == this->listSizeMax)
{ {
@@ -70,8 +81,7 @@ lstAdd(List *this, const void *item)
memcpy(this->list + (this->listSize * this->itemSize), item, this->itemSize); memcpy(this->list + (this->listSize * this->itemSize), item, this->itemSize);
this->listSize++; this->listSize++;
// Return list FUNCTION_TEST_RESULT(LIST, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -80,12 +90,19 @@ Get an item from the list
void * void *
lstGet(const List *this, unsigned int listIdx) lstGet(const List *this, unsigned int listIdx)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_PARAM(UINT, listIdx);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// Ensure list index is in range // Ensure list index is in range
if (listIdx >= this->listSize) if (listIdx >= this->listSize)
THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, this->listSize); THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, this->listSize);
// Return pointer to list item // Return pointer to list item
return this->list + (listIdx * this->itemSize); FUNCTION_TEST_RESULT(VOIDP, this->list + (listIdx * this->itemSize));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -94,7 +111,13 @@ Return the memory context for this list
MemContext * MemContext *
lstMemContext(const List *this) lstMemContext(const List *this)
{ {
return this->memContext; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(MEM_CONTEXT, this->memContext);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -103,10 +126,17 @@ Move the string list
List * List *
lstMove(List *this, MemContext *parentNew) lstMove(List *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextMove(this->memContext, parentNew); memContextMove(this->memContext, parentNew);
return this; FUNCTION_TEST_RESULT(LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -115,7 +145,13 @@ Return list size
unsigned int unsigned int
lstSize(const List *this) lstSize(const List *this)
{ {
return this->listSize; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, this->listSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -124,9 +160,41 @@ List sort
List * List *
lstSort(List *this, int (*comparator)(const void *, const void*)) lstSort(List *this, int (*comparator)(const void *, const void*))
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_PARAM(FUNCTIONP, comparator);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(comparator != NULL);
FUNCTION_TEST_END();
qsort(this->list, this->listSize, this->itemSize, comparator); qsort(this->list, this->listSize, this->itemSize, comparator);
return this; FUNCTION_TEST_RESULT(LIST, this);
}
/***********************************************************************************************************************************
Convert to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
lstToLog(const List *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
string = strNew("null");
else
string = strNewFmt("{size: %u}", this->listSize);
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
MEM_CONTEXT_TEMP_END();
return result;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -135,6 +203,12 @@ Free the string
void void
lstFree(List *this) lstFree(List *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(LIST, this);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -29,4 +29,14 @@ unsigned int lstSize(const List *this);
List *lstSort(List *this, int (*comparator)(const void *, const void*)); List *lstSort(List *this, int (*comparator)(const void *, const void*));
void lstFree(List *this); void lstFree(List *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t lstToLog(const List *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_LIST_TYPE \
List *
#define FUNCTION_DEBUG_LIST_FORMAT(value, buffer, bufferSize) \
lstToLog(value, buffer, bufferSize)
#endif #endif

View File

@@ -8,6 +8,7 @@ String Handler
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/type/string.h" #include "common/type/string.h"
@@ -27,6 +28,12 @@ Create a new string from a zero-terminated string
String * String *
strNew(const char *string) strNew(const char *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, string);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_END();
// Create object // Create object
String *this = memNew(sizeof(String)); String *this = memNew(sizeof(String));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
@@ -36,8 +43,7 @@ strNew(const char *string)
this->buffer = memNewRaw(this->size + 1); this->buffer = memNewRaw(this->size + 1);
strcpy(this->buffer, string); strcpy(this->buffer, string);
// Return buffer FUNCTION_TEST_RESULT(STRING, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -49,6 +55,12 @@ character will be used as a string.
String * String *
strNewBuf(const Buffer *buffer) strNewBuf(const Buffer *buffer)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_END();
// Create object // Create object
String *this = memNew(sizeof(String)); String *this = memNew(sizeof(String));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
@@ -59,8 +71,7 @@ strNewBuf(const Buffer *buffer)
memcpy(this->buffer, (char *)bufPtr(buffer), this->size); memcpy(this->buffer, (char *)bufPtr(buffer), this->size);
this->buffer[this->size] = 0; this->buffer[this->size] = 0;
// Return buffer FUNCTION_TEST_RESULT(STRING, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -69,6 +80,12 @@ Create a new string from a format string with parameters (i.e. sprintf)
String * String *
strNewFmt(const char *format, ...) strNewFmt(const char *format, ...)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, format);
FUNCTION_TEST_ASSERT(format != NULL);
FUNCTION_TEST_END();
// Create object // Create object
String *this = memNew(sizeof(String)); String *this = memNew(sizeof(String));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
@@ -85,8 +102,7 @@ strNewFmt(const char *format, ...)
vsnprintf(this->buffer, this->size + 1, format, argumentList); vsnprintf(this->buffer, this->size + 1, format, argumentList);
va_end(argumentList); va_end(argumentList);
// Return buffer FUNCTION_TEST_RESULT(STRING, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -97,6 +113,13 @@ The string may or may not be zero-terminated but we'll use that nomeclature sinc
String * String *
strNewN(const char *string, size_t size) strNewN(const char *string, size_t size)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(CHARP, string);
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_END();
// Create object // Create object
String *this = memNew(sizeof(String)); String *this = memNew(sizeof(String));
this->memContext = memContextCurrent(); this->memContext = memContextCurrent();
@@ -108,7 +131,7 @@ strNewN(const char *string, size_t size)
this->buffer[this->size] = 0; this->buffer[this->size] = 0;
// Return buffer // Return buffer
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -117,12 +140,18 @@ Return the file part of a string (i.e. everything after the last / or the entire
String * String *
strBase(const String *this) strBase(const String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
const char *end = this->buffer + this->size; const char *end = this->buffer + this->size;
while (end > this->buffer && *(end - 1) != '/') while (end > this->buffer && *(end - 1) != '/')
end--; end--;
return strNew(end); FUNCTION_TEST_RESULT(STRING, strNew(end));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -131,19 +160,35 @@ Does the string begin with the specified string?
bool bool
strBeginsWith(const String *this, const String *beginsWith) strBeginsWith(const String *this, const String *beginsWith)
{ {
return strBeginsWithZ(this, strPtr(beginsWith)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRING, beginsWith);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(beginsWith != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, strBeginsWithZ(this, strPtr(beginsWith)));
} }
bool bool
strBeginsWithZ(const String *this, const char *beginsWith) strBeginsWithZ(const String *this, const char *beginsWith)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, beginsWith);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(beginsWith != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
unsigned int beginsWithSize = (unsigned int)strlen(beginsWith); unsigned int beginsWithSize = (unsigned int)strlen(beginsWith);
if (this->size >= beginsWithSize) if (this->size >= beginsWithSize)
result = strncmp(strPtr(this), beginsWith, beginsWithSize) == 0; result = strncmp(strPtr(this), beginsWith, beginsWithSize) == 0;
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -152,6 +197,14 @@ Append a string
String * String *
strCat(String *this, const char *cat) strCat(String *this, const char *cat)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, cat);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(cat != NULL);
FUNCTION_TEST_END();
// Determine length of string to append // Determine length of string to append
size_t sizeGrow = strlen(cat); size_t sizeGrow = strlen(cat);
@@ -165,7 +218,7 @@ strCat(String *this, const char *cat)
strcpy(this->buffer + this->size, cat); strcpy(this->buffer + this->size, cat);
this->size += sizeGrow; this->size += sizeGrow;
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -174,6 +227,14 @@ Append a formatted string
String * String *
strCatFmt(String *this, const char *format, ...) strCatFmt(String *this, const char *format, ...)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, format);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(format != NULL);
FUNCTION_TEST_END();
// Determine how long the allocated string needs to be // Determine how long the allocated string needs to be
va_list argumentList; va_list argumentList;
va_start(argumentList, format); va_start(argumentList, format);
@@ -193,8 +254,7 @@ strCatFmt(String *this, const char *format, ...)
this->size += sizeGrow; this->size += sizeGrow;
// Return buffer FUNCTION_TEST_RESULT(STRING, this);
return this;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -203,13 +263,29 @@ C-style string compare
int int
strCmp(const String *this, const String *compare) strCmp(const String *this, const String *compare)
{ {
return strcmp(strPtr(this), strPtr(compare)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRING, compare);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(compare != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(INT, strcmp(strPtr(this), strPtr(compare)));
} }
int int
strCmpZ(const String *this, const char *compare) strCmpZ(const String *this, const char *compare)
{ {
return strcmp(strPtr(this), compare); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, compare);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(compare != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(INT, strcmp(strPtr(this), compare));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -218,12 +294,16 @@ Duplicate a string from an existing string
String * String *
strDup(const String *this) strDup(const String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
if (this != NULL) if (this != NULL)
result = strNew(strPtr(this)); result = strNew(strPtr(this));
return result; FUNCTION_TEST_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -232,19 +312,35 @@ Does the string end with the specified string?
bool bool
strEndsWith(const String *this, const String *endsWith) strEndsWith(const String *this, const String *endsWith)
{ {
return strEndsWithZ(this, strPtr(endsWith)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRING, endsWith);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(endsWith != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, strEndsWithZ(this, strPtr(endsWith)));
} }
bool bool
strEndsWithZ(const String *this, const char *endsWith) strEndsWithZ(const String *this, const char *endsWith)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, endsWith);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(endsWith != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
unsigned int endsWithSize = (unsigned int)strlen(endsWith); unsigned int endsWithSize = (unsigned int)strlen(endsWith);
if (this->size >= endsWithSize) if (this->size >= endsWithSize)
result = strcmp(strPtr(this) + (this->size - endsWithSize), endsWith) == 0; result = strcmp(strPtr(this) + (this->size - endsWithSize), endsWith) == 0;
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -256,18 +352,34 @@ would need a call to strlen().
bool bool
strEq(const String *this, const String *compare) strEq(const String *this, const String *compare)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRING, compare);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(compare != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
if (this->size == compare->size) if (this->size == compare->size)
result = strcmp(strPtr(this), strPtr(compare)) == 0; result = strcmp(strPtr(this), strPtr(compare)) == 0;
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
bool bool
strEqZ(const String *this, const char *compare) strEqZ(const String *this, const char *compare)
{ {
return strcmp(strPtr(this), compare) == 0; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, compare);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(compare != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, strcmp(strPtr(this), compare) == 0);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -276,10 +388,16 @@ Upper-case the first letter
String * String *
strFirstUpper(String *this) strFirstUpper(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (this->size > 0) if (this->size > 0)
this->buffer[0] = (char)toupper(this->buffer[0]); this->buffer[0] = (char)toupper(this->buffer[0]);
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -288,10 +406,16 @@ Lower-case the first letter
String * String *
strFirstLower(String *this) strFirstLower(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (this->size > 0) if (this->size > 0)
this->buffer[0] = (char)tolower(this->buffer[0]); this->buffer[0] = (char)tolower(this->buffer[0]);
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -300,11 +424,17 @@ Upper-case entire string
String * String *
strUpper(String *this) strUpper(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (this->size > 0) if (this->size > 0)
for (unsigned int idx = 0; idx <= this->size; idx++) for (unsigned int idx = 0; idx <= this->size; idx++)
this->buffer[idx] = (char)toupper(this->buffer[idx]); this->buffer[idx] = (char)toupper(this->buffer[idx]);
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -313,11 +443,17 @@ Upper-case entire string
String * String *
strLower(String *this) strLower(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (this->size > 0) if (this->size > 0)
for (unsigned int idx = 0; idx <= this->size; idx++) for (unsigned int idx = 0; idx <= this->size; idx++)
this->buffer[idx] = (char)tolower(this->buffer[idx]); this->buffer[idx] = (char)tolower(this->buffer[idx]);
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -326,12 +462,19 @@ Return the path part of a string (i.e. everything before the last / or "" if the
String * String *
strPath(const String *this) strPath(const String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
const char *end = this->buffer + this->size; const char *end = this->buffer + this->size;
while (end > this->buffer && *(end - 1) != '/') while (end > this->buffer && *(end - 1) != '/')
end--; end--;
return strNewN(this->buffer, end - this->buffer <= 1 ? (size_t)(end - this->buffer) : (size_t)(end - this->buffer - 1)); FUNCTION_TEST_RESULT(
STRING, strNewN(this->buffer, end - this->buffer <= 1 ? (size_t)(end - this->buffer) : (size_t)(end - this->buffer - 1)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -340,12 +483,47 @@ Return string ptr
const char * const char *
strPtr(const String *this) strPtr(const String *this)
{ {
const char *result = NULL; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_END();
char *result = NULL;
if (this != NULL) if (this != NULL)
result = (const char *)this->buffer; result = this->buffer;
return result; FUNCTION_TEST_RESULT(CHARP, result);
}
/***********************************************************************************************************************************
Quote a string
***********************************************************************************************************************************/
String *
strQuote(const String *this, const String *quote)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRING, quote);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(quote != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, strQuoteZ(this, strPtr(quote)));
}
String *
strQuoteZ(const String *this, const char *quote)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(STRINGZ, quote);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(quote != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, strNewFmt("%s%s%s", quote, strPtr(this), quote));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -354,7 +532,15 @@ Return a substring given only the start position
String * String *
strSub(const String *this, size_t start) strSub(const String *this, size_t start)
{ {
return strSubN(this, start, this->size - start); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(SIZE, start);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(start < this->size);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, strSubN(this, start, this->size - start));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -363,10 +549,17 @@ Return a substring given the start position and size
String * String *
strSubN(const String *this, size_t start, size_t size) strSubN(const String *this, size_t start, size_t size)
{ {
ASSERT(start < this->size); FUNCTION_TEST_BEGIN();
ASSERT(start + size <= this->size); FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_PARAM(SIZE, start);
FUNCTION_TEST_PARAM(SIZE, size);
return strNewN(this->buffer + start, size); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(start < this->size);
FUNCTION_TEST_ASSERT(start + size <= this->size);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, strNewN(this->buffer + start, size));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -375,7 +568,13 @@ Return string size
size_t size_t
strSize(const String *this) strSize(const String *this)
{ {
return this->size; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -384,6 +583,12 @@ Trim whitespace from the beginnning and end of a string
String * String *
strTrim(String *this) strTrim(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
// Nothing to trim if size is zero // Nothing to trim if size is zero
if (this->size > 0) if (this->size > 0)
{ {
@@ -420,7 +625,7 @@ strTrim(String *this)
} }
} }
return this; FUNCTION_TEST_RESULT(STRING, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -429,16 +634,23 @@ Return the index to the location of the the first occurrence of a character with
int int
strChr(const String *this, char chr) strChr(const String *this, char chr)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
int result = -1; int result = -1;
if (this->size > 0) if (this->size > 0)
{ {
const char *ptr = strchr(this->buffer, chr); const char *ptr = strchr(this->buffer, chr);
if (ptr != NULL) if (ptr != NULL)
result = (int)(ptr - this->buffer); result = (int)(ptr - this->buffer);
} }
return result; FUNCTION_TEST_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -447,9 +659,12 @@ Truncate the end of a string from the index provided to the current end (e.g. 12
String * String *
strTrunc(String *this, int idx) strTrunc(String *this, int idx)
{ {
// If the index position is outside the array boundaries then error FUNCTION_TEST_BEGIN();
if (idx < 0 || (size_t)idx > this->size) FUNCTION_TEST_PARAM(STRING, this);
THROW_FMT(AssertError, "index passed is outside the string boundaries");
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(idx >= 0 && (size_t)idx <= this->size);
FUNCTION_TEST_END();
if (this->size > 0) if (this->size > 0)
{ {
@@ -465,7 +680,31 @@ strTrunc(String *this, int idx)
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
return this; FUNCTION_TEST_RESULT(STRING, this);
}
/***********************************************************************************************************************************
Convert to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
strToLog(const String *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
string = strNew("null");
else
string = strNewFmt("{\"%s\"}", strPtr(this));
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
MEM_CONTEXT_TEMP_END();
return result;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -474,6 +713,10 @@ Free the string
void void
strFree(String *this) strFree(String *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, this);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
{ {
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
@@ -483,4 +726,6 @@ strFree(String *this)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -37,6 +37,8 @@ String *strUpper(String *this);
String *strLower(String *this); String *strLower(String *this);
String *strPath(const String *this); String *strPath(const String *this);
const char *strPtr(const String *this); const char *strPtr(const String *this);
String *strQuote(const String *this, const String *quote);
String *strQuoteZ(const String *this, const char *quote);
size_t strSize(const String *this); size_t strSize(const String *this);
String *strSub(const String *this, size_t start); String *strSub(const String *this, size_t start);
String *strSubN(const String *this, size_t start, size_t size); String *strSubN(const String *this, size_t start, size_t size);
@@ -46,4 +48,24 @@ String *strTrunc(String *this, int idx);
void strFree(String *this); void strFree(String *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t strToLog(const String *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_CONST_STRING_TYPE \
const String *
#define FUNCTION_DEBUG_CONST_STRING_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_STRING_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_STRING_TYPE \
String *
#define FUNCTION_DEBUG_STRING_FORMAT(value, buffer, bufferSize) \
strToLog(value, buffer, bufferSize)
#define FUNCTION_DEBUG_STRINGP_TYPE \
const String **
#define FUNCTION_DEBUG_STRINGP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "String **", buffer, bufferSize)
#endif #endif

View File

@@ -2,9 +2,12 @@
String List Handler String List Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/type/list.h" #include "common/type/list.h"
#include "common/type/stringList.h" #include "common/type/stringList.h"
@@ -15,7 +18,8 @@ Wrapper for lstNew()
StringList * StringList *
strLstNew() strLstNew()
{ {
return (StringList *)lstNew(sizeof(String *)); FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(STRING_LIST, (StringList *)lstNew(sizeof(String *)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -24,7 +28,14 @@ Internal add -- the string must have been created in the list's mem context befo
static StringList * static StringList *
strLstAddInternal(StringList *this, String *string) strLstAddInternal(StringList *this, String *string)
{ {
return (StringList *)lstAdd((List *)this, &string); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING_LIST, (StringList *)lstAdd((List *)this, &string));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -33,12 +44,28 @@ Split a string into a string list based on a delimiter
StringList * StringList *
strLstNewSplit(const String *string, const String *delimiter) strLstNewSplit(const String *string, const String *delimiter)
{ {
return strLstNewSplitZ(string, strPtr(delimiter)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_PARAM(STRING, delimiter);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_ASSERT(delimiter != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING_LIST, strLstNewSplitZ(string, strPtr(delimiter)));
} }
StringList * StringList *
strLstNewSplitZ(const String *string, const char *delimiter) strLstNewSplitZ(const String *string, const char *delimiter)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_PARAM(STRINGZ, delimiter);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_ASSERT(delimiter != NULL);
FUNCTION_TEST_END();
// Create the list // Create the list
StringList *this = strLstNew(); StringList *this = strLstNew();
@@ -69,7 +96,7 @@ strLstNewSplitZ(const String *string, const char *delimiter)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(STRING_LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -81,12 +108,30 @@ breaking up test on spaces, for example.
StringList * StringList *
strLstNewSplitSize(const String *string, const String *delimiter, size_t size) strLstNewSplitSize(const String *string, const String *delimiter, size_t size)
{ {
return strLstNewSplitSizeZ(string, strPtr(delimiter), size); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_PARAM(STRING, delimiter);
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_ASSERT(delimiter != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING_LIST, strLstNewSplitSizeZ(string, strPtr(delimiter), size));
} }
StringList * StringList *
strLstNewSplitSizeZ(const String *string, const char *delimiter, size_t size) strLstNewSplitSizeZ(const String *string, const char *delimiter, size_t size)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_PARAM(STRINGZ, delimiter);
FUNCTION_TEST_PARAM(SIZE, size);
FUNCTION_TEST_ASSERT(string != NULL);
FUNCTION_TEST_ASSERT(delimiter != NULL);
FUNCTION_TEST_END();
// Create the list // Create the list
StringList *this = strLstNew(); StringList *this = strLstNew();
@@ -135,7 +180,7 @@ strLstNewSplitSizeZ(const String *string, const char *delimiter, size_t size)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(STRING_LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -144,6 +189,12 @@ New string list from a variant list -- all variants in the list must be type str
StringList * StringList *
strLstNewVarLst(const VariantList *sourceList) strLstNewVarLst(const VariantList *sourceList)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, sourceList);
FUNCTION_TEST_ASSERT(sourceList != NULL);
FUNCTION_TEST_END();
// Create the list // Create the list
StringList *this = strLstNew(); StringList *this = strLstNew();
@@ -155,7 +206,7 @@ strLstNewVarLst(const VariantList *sourceList)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(STRING_LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -164,6 +215,12 @@ Duplicate a string list
StringList * StringList *
strLstDup(const StringList *sourceList) strLstDup(const StringList *sourceList)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, sourceList);
FUNCTION_TEST_ASSERT(sourceList != NULL);
FUNCTION_TEST_END();
// Create the list // Create the list
StringList *this = strLstNew(); StringList *this = strLstNew();
@@ -175,7 +232,7 @@ strLstDup(const StringList *sourceList)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return this; FUNCTION_TEST_RESULT(STRING_LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -184,6 +241,13 @@ Does the specified string exist in the list?
bool bool
strLstExists(const StringList *this, const String *string) strLstExists(const StringList *this, const String *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++) for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++)
@@ -195,12 +259,19 @@ strLstExists(const StringList *this, const String *string)
} }
} }
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
bool bool
strLstExistsZ(const StringList *this, const char *cstring) strLstExistsZ(const StringList *this, const char *cstring)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRINGZ, cstring);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++) for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++)
@@ -212,7 +283,7 @@ strLstExistsZ(const StringList *this, const char *cstring)
} }
} }
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -221,6 +292,13 @@ Wrapper for lstAdd()
StringList * StringList *
strLstAdd(StringList *this, const String *string) strLstAdd(StringList *this, const String *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRING, string);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
StringList *result = NULL; StringList *result = NULL;
MEM_CONTEXT_BEGIN(lstMemContext((List *)this)) MEM_CONTEXT_BEGIN(lstMemContext((List *)this))
@@ -229,7 +307,7 @@ strLstAdd(StringList *this, const String *string)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return result; FUNCTION_TEST_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -238,6 +316,13 @@ Add a zero-terminated string to the list
StringList * StringList *
strLstAddZ(StringList *this, const char *string) strLstAddZ(StringList *this, const char *string)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRINGZ, string);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
StringList *result = NULL; StringList *result = NULL;
MEM_CONTEXT_BEGIN(lstMemContext((List *)this)) MEM_CONTEXT_BEGIN(lstMemContext((List *)this))
@@ -246,7 +331,7 @@ strLstAddZ(StringList *this, const char *string)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
return result; FUNCTION_TEST_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -255,7 +340,14 @@ Wrapper for lstGet()
String * String *
strLstGet(const StringList *this, unsigned int listIdx) strLstGet(const StringList *this, unsigned int listIdx)
{ {
return *(String **)lstGet((List *)this, listIdx); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(UINT, listIdx);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, *(String **)lstGet((List *)this, listIdx));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -264,6 +356,33 @@ Join a list of strings into a single string using the specified separator
String * String *
strLstJoin(const StringList *this, const char *separator) strLstJoin(const StringList *this, const char *separator)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRINGZ, separator);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(separator != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRING, strLstJoinQuote(this, separator, ""));
}
/***********************************************************************************************************************************
Join a list of strings into a single string using the specified separator and quote with specified quote character
***********************************************************************************************************************************/
String *
strLstJoinQuote(const StringList *this, const char *separator, const char *quote)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(STRINGZ, separator);
FUNCTION_TEST_PARAM(STRINGZ, quote);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(separator != NULL);
FUNCTION_TEST_ASSERT(quote != NULL);
FUNCTION_TEST_END();
String *join = strNew(""); String *join = strNew("");
for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++) for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++)
@@ -274,10 +393,10 @@ strLstJoin(const StringList *this, const char *separator)
if (strLstGet(this, listIdx) == NULL) if (strLstGet(this, listIdx) == NULL)
strCat(join, "[NULL]"); strCat(join, "[NULL]");
else else
strCat(join, strPtr(strLstGet(this, listIdx))); strCatFmt(join, "%s%s%s", quote, strPtr(strLstGet(this, listIdx)), quote);
} }
return join; FUNCTION_TEST_RESULT(STRING, join);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -286,8 +405,16 @@ Move the string list
StringList * StringList *
strLstMove(StringList *this, MemContext *parentNew) strLstMove(StringList *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
lstMove((List *)this, parentNew); lstMove((List *)this, parentNew);
return this;
FUNCTION_TEST_RESULT(STRING_LIST, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -297,6 +424,12 @@ this array, though it is OK to modify the array itself.
const char ** const char **
strLstPtr(const StringList *this) strLstPtr(const StringList *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
const char **list = memNew(strLstSize(this) * sizeof(char *)); const char **list = memNew(strLstSize(this) * sizeof(char *));
for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++) for (unsigned int listIdx = 0; listIdx < strLstSize(this); listIdx++)
@@ -307,7 +440,7 @@ strLstPtr(const StringList *this)
list[listIdx] = strPtr(strLstGet(this, listIdx)); list[listIdx] = strPtr(strLstGet(this, listIdx));
} }
return list; FUNCTION_TEST_RESULT(CONST_CHARPP, list);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -316,7 +449,13 @@ Wrapper for lstSize()
unsigned int unsigned int
strLstSize(const StringList *this) strLstSize(const StringList *this)
{ {
return lstSize((List *)this); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, lstSize((List *)this));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -325,18 +464,41 @@ Sort strings in alphabetical order
static int static int
sortAscComparator(const void *item1, const void *item2) sortAscComparator(const void *item1, const void *item2)
{ {
return strCmp(*(String **)item1, *(String **)item2); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VOIDP, item1);
FUNCTION_TEST_PARAM(VOIDP, item2);
FUNCTION_TEST_ASSERT(item1 != NULL);
FUNCTION_TEST_ASSERT(item2 != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(INT, strCmp(*(String **)item1, *(String **)item2));
} }
static int static int
sortDescComparator(const void *item1, const void *item2) sortDescComparator(const void *item1, const void *item2)
{ {
return strCmp(*(String **)item2, *(String **)item1); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VOIDP, item1);
FUNCTION_TEST_PARAM(VOIDP, item2);
FUNCTION_TEST_ASSERT(item1 != NULL);
FUNCTION_TEST_ASSERT(item2 != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(INT, strCmp(*(String **)item2, *(String **)item1));
} }
StringList * StringList *
strLstSort(StringList *this, SortOrder sortOrder) strLstSort(StringList *this, SortOrder sortOrder)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_PARAM(ENUM, sortOrder);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
switch (sortOrder) switch (sortOrder)
{ {
case sortOrderAsc: case sortOrderAsc:
@@ -351,7 +513,32 @@ strLstSort(StringList *this, SortOrder sortOrder)
break; break;
} }
} }
return this;
FUNCTION_TEST_RESULT(STRING_LIST, this);
}
/***********************************************************************************************************************************
Convert to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
strLstToLog(const StringList *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
string = strNew("null");
else
string = strNewFmt("{[%s]}", strPtr(strLstJoinQuote(this, ", ", "\"")));
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
MEM_CONTEXT_TEMP_END();
return result;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -360,5 +547,11 @@ Wrapper for lstFree()
void void
strLstFree(StringList *this) strLstFree(StringList *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, this);
FUNCTION_TEST_END();
lstFree((List *)this); lstFree((List *)this);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -39,6 +39,7 @@ bool strLstExists(const StringList *this, const String *string);
bool strLstExistsZ(const StringList *this, const char *cstring); bool strLstExistsZ(const StringList *this, const char *cstring);
String *strLstGet(const StringList *this, unsigned int listIdx); String *strLstGet(const StringList *this, unsigned int listIdx);
String *strLstJoin(const StringList *this, const char *separator); String *strLstJoin(const StringList *this, const char *separator);
String *strLstJoinQuote(const StringList *this, const char *separator, const char *quote);
StringList * strLstMove(StringList *this, MemContext *parentNew); StringList * strLstMove(StringList *this, MemContext *parentNew);
const char **strLstPtr(const StringList *this); const char **strLstPtr(const StringList *this);
unsigned int strLstSize(const StringList *this); unsigned int strLstSize(const StringList *this);
@@ -46,4 +47,14 @@ StringList *strLstSort(StringList *this, SortOrder sortOrder);
void strLstFree(StringList *this); void strLstFree(StringList *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t strLstToLog(const StringList *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_STRING_LIST_TYPE \
StringList *
#define FUNCTION_DEBUG_STRING_LIST_FORMAT(value, buffer, bufferSize) \
strLstToLog(value, buffer, bufferSize)
#endif #endif

View File

@@ -8,7 +8,9 @@ Variant Data Type
#include <strings.h> #include <strings.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/type/convert.h"
#include "common/type/variant.h" #include "common/type/variant.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -40,9 +42,14 @@ New variant of any supported type
static Variant * static Variant *
varNewInternal(VariantType type, void *data, size_t dataSize) varNewInternal(VariantType type, void *data, size_t dataSize)
{ {
// Make sure there is some data to store FUNCTION_TEST_BEGIN();
ASSERT_DEBUG(dataSize > 0); FUNCTION_TEST_PARAM(ENUM, type);
ASSERT_DEBUG(data != NULL); FUNCTION_TEST_PARAM(VOIDP, data);
FUNCTION_TEST_PARAM(SIZE, dataSize);
FUNCTION_TEST_ASSERT(data != NULL);
FUNCTION_TEST_ASSERT(dataSize > 0);
FUNCTION_TEST_END();
// Allocate memory for the variant and set the type // Allocate memory for the variant and set the type
Variant *this = memNew(sizeof(Variant) + dataSize); Variant *this = memNew(sizeof(Variant) + dataSize);
@@ -52,7 +59,7 @@ varNewInternal(VariantType type, void *data, size_t dataSize)
// Copy data // Copy data
memcpy((unsigned char *)this + sizeof(Variant), data, dataSize); memcpy((unsigned char *)this + sizeof(Variant), data, dataSize);
return this; FUNCTION_TEST_RESULT(VARIANT, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -61,7 +68,13 @@ Get a pointer to the data stored in the variant. This hides the complicated poi
static void * static void *
varData(const Variant *this) varData(const Variant *this)
{ {
return (void *)((unsigned char *)this + sizeof(Variant)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VOIDP, (void *)((unsigned char *)this + sizeof(Variant)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -70,6 +83,10 @@ Duplicate a variant
Variant * Variant *
varDup(const Variant *this) varDup(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_END();
Variant *result = NULL; Variant *result = NULL;
if (this != NULL) if (this != NULL)
@@ -121,7 +138,7 @@ varDup(const Variant *this)
} }
} }
return result; FUNCTION_TEST_RESULT(VARIANT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -130,6 +147,11 @@ Test if variants are equal
bool bool
varEq(const Variant *this1, const Variant *this2) varEq(const Variant *this1, const Variant *this2)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this1);
FUNCTION_TEST_PARAM(VARIANT, this2);
FUNCTION_TEST_END();
bool result = false; bool result = false;
// Test if both variants are non-null // Test if both variants are non-null
@@ -180,7 +202,7 @@ varEq(const Variant *this1, const Variant *this2)
else else
result = this1 == NULL && this2 == NULL; result = this1 == NULL && this2 == NULL;
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -189,7 +211,13 @@ Get variant type
VariantType VariantType
varType(const Variant *this) varType(const Variant *this)
{ {
return this->type; FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, this->type);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -198,7 +226,11 @@ New bool variant
Variant * Variant *
varNewBool(bool data) varNewBool(bool data)
{ {
return varNewInternal(varTypeBool, (void *)&data, sizeof(data)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BOOL, data);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeBool, (void *)&data, sizeof(data)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -207,12 +239,15 @@ Return bool
bool bool
varBool(const Variant *this) varBool(const Variant *this)
{ {
// Only valid for int FUNCTION_TEST_BEGIN();
if (this->type != varTypeBool) FUNCTION_TEST_PARAM(VARIANT, this);
THROW(AssertError, "variant type is not bool");
// Get the int FUNCTION_TEST_ASSERT(this != NULL);
return *((bool *)varData(this)); FUNCTION_TEST_END();
ASSERT(this->type == varTypeBool);
FUNCTION_TEST_RESULT(BOOL, *((bool *)varData(this)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -221,6 +256,12 @@ Return bool regardless of variant type
bool bool
varBoolForce(const Variant *this) varBoolForce(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
bool result = false; bool result = false;
switch (this->type) switch (this->type)
@@ -268,7 +309,7 @@ varBoolForce(const Variant *this)
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeBool]); THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeBool]);
} }
return result; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -277,7 +318,11 @@ New double variant
Variant * Variant *
varNewDbl(double data) varNewDbl(double data)
{ {
return varNewInternal(varTypeDouble, (unsigned char *)&data, sizeof(data)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(DOUBLE, data);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeDouble, (unsigned char *)&data, sizeof(data)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -286,12 +331,15 @@ Return double
double double
varDbl(const Variant *this) varDbl(const Variant *this)
{ {
// Only valid for double FUNCTION_TEST_BEGIN();
if (this->type != varTypeDouble) FUNCTION_TEST_PARAM(VARIANT, this);
THROW(AssertError, "variant type is not double");
// Get the int FUNCTION_TEST_ASSERT(this != NULL);
return *((double *)varData(this)); FUNCTION_TEST_END();
ASSERT(this->type == varTypeDouble);
FUNCTION_TEST_RESULT(DOUBLE, *((double *)varData(this)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -300,6 +348,12 @@ Return double regardless of variant type
double double
varDblForce(const Variant *this) varDblForce(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
double result = 0; double result = 0;
switch (this->type) switch (this->type)
@@ -330,15 +384,7 @@ varDblForce(const Variant *this)
case varTypeString: case varTypeString:
{ {
sscanf(strPtr(varStr(this)), "%lf", &result); result = cvtZToDouble(strPtr(varStr(this)));
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
{
THROW_FMT(
FormatError, "unable to force %s '%s' to %s", variantTypeName[this->type], strPtr(varStr(this)),
variantTypeName[varTypeDouble]);
}
break; break;
} }
@@ -346,7 +392,7 @@ varDblForce(const Variant *this)
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeDouble]); THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeDouble]);
} }
return result; FUNCTION_TEST_RESULT(DOUBLE, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -355,7 +401,11 @@ New int variant
Variant * Variant *
varNewInt(int data) varNewInt(int data)
{ {
return varNewInternal(varTypeInt, (void *)&data, sizeof(data)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, data);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeInt, (void *)&data, sizeof(data)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -364,12 +414,15 @@ Return int
int int
varInt(const Variant *this) varInt(const Variant *this)
{ {
// Only valid for int FUNCTION_TEST_BEGIN();
if (this->type != varTypeInt) FUNCTION_TEST_PARAM(VARIANT, this);
THROW(AssertError, "variant type is not int");
// Get the int FUNCTION_TEST_ASSERT(this != NULL);
return *((int *)varData(this)); FUNCTION_TEST_END();
ASSERT(this->type == varTypeInt);
FUNCTION_TEST_RESULT(INT, *((int *)varData(this)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -378,6 +431,12 @@ Return int regardless of variant type
int int
varIntForce(const Variant *this) varIntForce(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
int result = 0; int result = 0;
switch (this->type) switch (this->type)
@@ -409,11 +468,7 @@ varIntForce(const Variant *this)
case varTypeString: case varTypeString:
{ {
result = atoi(strPtr(varStr(this))); result = cvtZToInt(strPtr(varStr(this)));
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
THROW_FMT(FormatError, "unable to convert str '%s' to int", strPtr(varStr(this)));
break; break;
} }
@@ -421,7 +476,7 @@ varIntForce(const Variant *this)
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]); THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
} }
return result; FUNCTION_TEST_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -430,7 +485,11 @@ New int64 variant
Variant * Variant *
varNewInt64(int64_t data) varNewInt64(int64_t data)
{ {
return varNewInternal(varTypeInt64, (void *)&data, sizeof(data)); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT64, data);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeInt64, (void *)&data, sizeof(data)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -439,12 +498,15 @@ Return int64
int64_t int64_t
varInt64(const Variant *this) varInt64(const Variant *this)
{ {
// Only valid for int FUNCTION_TEST_BEGIN();
if (this->type != varTypeInt64) FUNCTION_TEST_PARAM(VARIANT, this);
THROW_FMT(AssertError, "variant type is not %s", variantTypeName[varTypeInt64]);
// Get the int FUNCTION_TEST_ASSERT(this != NULL);
return *((int64_t *)varData(this)); FUNCTION_TEST_END();
ASSERT(this->type == varTypeInt64);
FUNCTION_TEST_RESULT(INT64, *((int64_t *)varData(this)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -453,6 +515,12 @@ Return int64 regardless of variant type
int64_t int64_t
varInt64Force(const Variant *this) varInt64Force(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
int64_t result = 0; int64_t result = 0;
switch (this->type) switch (this->type)
@@ -477,16 +545,7 @@ varInt64Force(const Variant *this)
case varTypeString: case varTypeString:
{ {
result = atoll(strPtr(varStr(this))); result = cvtZToInt64(strPtr(varStr(this)));
char buffer[32];
snprintf(buffer, sizeof(buffer), "%" PRId64, result);
if (strcmp(strPtr(varStr(this)), buffer) != 0)
THROW_FMT(
FormatError, "unable to convert %s '%s' to %s", variantTypeName[varTypeString], strPtr(varStr(this)),
variantTypeName[varTypeInt64]);
break; break;
} }
@@ -494,7 +553,7 @@ varInt64Force(const Variant *this)
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]); THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]);
} }
return result; FUNCTION_TEST_RESULT(INT64, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -503,9 +562,12 @@ New key/value variant
Variant * Variant *
varNewKv() varNewKv()
{ {
// Create the variant FUNCTION_TEST_VOID();
// Create a new kv for the variant
KeyValue *data = kvNew(); KeyValue *data = kvNew();
return varNewInternal(varTypeKeyValue, (void *)&data, sizeof(data));
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeKeyValue, (void *)&data, sizeof(data)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -514,19 +576,19 @@ Return key/value
KeyValue * KeyValue *
varKv(const Variant *this) varKv(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_END();
KeyValue *result = NULL; KeyValue *result = NULL;
if (this != NULL) if (this != NULL)
{ {
// Only valid for key/value ASSERT(this->type == varTypeKeyValue);
if (this->type != varTypeKeyValue)
THROW(AssertError, "variant type is not 'KeyValue'");
// Get the string
result = *((KeyValue **)varData(this)); result = *((KeyValue **)varData(this));
} }
return result; FUNCTION_TEST_RESULT(KEY_VALUE, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -535,13 +597,16 @@ New string variant
Variant * Variant *
varNewStr(const String *data) varNewStr(const String *data)
{ {
// Make sure the string is not NULL FUNCTION_TEST_BEGIN();
if (data == NULL) FUNCTION_TEST_PARAM(STRING, data);
THROW(AssertError, "string variant cannot be NULL");
// Create the variant FUNCTION_TEST_ASSERT(data != NULL);
FUNCTION_TEST_END();
// Create a copy of the string for the variant
String *dataCopy = strDup(data); String *dataCopy = strDup(data);
return varNewInternal(varTypeString, (void *)&dataCopy, sizeof(dataCopy));
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeString, (void *)&dataCopy, sizeof(dataCopy)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -550,13 +615,16 @@ New string variant from a zero-terminated string
Variant * Variant *
varNewStrZ(const char *data) varNewStrZ(const char *data)
{ {
// Make sure the string is not NULL FUNCTION_TEST_BEGIN();
if (data == NULL) FUNCTION_TEST_PARAM(STRINGZ, data);
THROW(AssertError, "zero-terminated string cannot be NULL");
// Create the variant FUNCTION_TEST_ASSERT(data != NULL);
FUNCTION_TEST_END();
// Create a string for the variant
String *dataCopy = strNew(data); String *dataCopy = strNew(data);
return varNewInternal(varTypeString, (void *)&dataCopy, sizeof(dataCopy));
FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeString, (void *)&dataCopy, sizeof(dataCopy)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -565,19 +633,19 @@ Return string
String * String *
varStr(const Variant *this) varStr(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
if (this != NULL) if (this != NULL)
{ {
// Only valid for strings ASSERT(this->type == varTypeString);
if (this->type != varTypeString)
THROW(AssertError, "variant type is not string");
// Get the string
result = *((String **)varData(this)); result = *((String **)varData(this));
} }
return result; FUNCTION_TEST_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -586,60 +654,51 @@ Return string regardless of variant type
String * String *
varStrForce(const Variant *this) varStrForce(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
switch (varType(this)) switch (varType(this))
{ {
case varTypeBool: case varTypeBool:
{ {
if (varBool(this)) char working[6];
result = strNew("true");
else cvtBoolToZ(varBool(this), working, sizeof(working));
result = strNew("false"); result = strNew(working);
break; break;
} }
case varTypeDouble: case varTypeDouble:
{ {
// Convert to a string char working[64];
String *working = strNewFmt("%f", varDbl(this));
// Any formatted double should be at least 8 characters, i.e. 0.000000 cvtDoubleToZ(varDbl(this), working, sizeof(working));
ASSERT_DEBUG(strSize(working) >= 8); result = strNew(working);
// Any formatted double should have a decimal point
ASSERT_DEBUG(strchr(strPtr(working), '.') != NULL);
// Strip off any final 0s and the decimal point if there are no non-zero digits after it
const char *begin = strPtr(working);
const char *end = begin + strSize(working) - 1;
while (*end == '0' || *end == '.')
{
// It should not be possible to go past the beginning because format "%f" will always write a decimal point
ASSERT_DEBUG(end > begin);
end--;
if (*(end + 1) == '.')
break;
}
result = strNewN(begin, (size_t)(end - begin + 1));
strFree(working);
break; break;
} }
case varTypeInt: case varTypeInt:
{ {
result = strNewFmt("%d", varInt(this)); char working[64];
cvtIntToZ(varInt(this), working, sizeof(working));
result = strNew(working);
break; break;
} }
case varTypeInt64: case varTypeInt64:
{ {
result = strNewFmt("%" PRId64, varInt64(this)); char working[64];
cvtInt64ToZ(varInt64(this), working, sizeof(working));
result = strNew(working);
break; break;
} }
@@ -654,7 +713,7 @@ varStrForce(const Variant *this)
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeString]); THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeString]);
} }
return result; FUNCTION_TEST_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -663,20 +722,16 @@ New variant list variant
Variant * Variant *
varNewVarLst(const VariantList *data) varNewVarLst(const VariantList *data)
{ {
// Create the variant FUNCTION_TEST_BEGIN();
VariantList *dataCopy = varLstDup(data); FUNCTION_TEST_PARAM(VARIANT_LIST, data);
return varNewInternal(varTypeVariantList, (void *)&dataCopy, sizeof(dataCopy));
}
/*********************************************************************************************************************************** FUNCTION_TEST_ASSERT(data != NULL);
New empty variant list variant FUNCTION_TEST_END();
***********************************************************************************************************************************/
Variant * // Copy variant list for the variant
varNewVarLstEmpty() VariantList *dataCopy = varLstDup(data);
{
// Create the variant FUNCTION_TEST_RESULT(VARIANT, varNewInternal(varTypeVariantList, (void *)&dataCopy, sizeof(dataCopy)));
VariantList *data = varLstNew();
return varNewInternal(varTypeVariantList, (void *)&data, sizeof(data));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -685,18 +740,77 @@ Return key/value
VariantList * VariantList *
varVarLst(const Variant *this) varVarLst(const Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_END();
VariantList *result = NULL; VariantList *result = NULL;
if (this != NULL) if (this != NULL)
{ {
// Only valid for key/value ASSERT(this->type == varTypeVariantList);
if (this->type != varTypeVariantList)
THROW_FMT(AssertError, "variant type is not '%s'", variantTypeName[varTypeVariantList]);
// Get the string
result = *((VariantList **)varData(this)); result = *((VariantList **)varData(this));
} }
FUNCTION_TEST_RESULT(VARIANT_LIST, result);
}
/***********************************************************************************************************************************
Convert variant to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
varToLog(const Variant *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
{
string = strNew("null");
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
else
{
switch (varType(this))
{
case varTypeString:
{
String *temp = varStrForce(this);
string = strNewFmt("\"%s\"", strPtr(temp));
strFree(temp);
break;
}
case varTypeKeyValue:
{
string = strNew("KeyValue");
break;
}
case varTypeVariantList:
{
string = strNew("VariantList");
break;
}
case varTypeBool:
case varTypeDouble:
case varTypeInt:
case varTypeInt64:
{
string = varStrForce(this);
break;
}
}
result = (size_t)snprintf(buffer, bufferSize, "{%s}", strPtr(string));
}
}
MEM_CONTEXT_TEMP_END();
return result; return result;
} }
@@ -706,6 +820,10 @@ Free variant
void void
varFree(Variant *this) varFree(Variant *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT, this);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
{ {
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_BEGIN(this->memContext)
@@ -742,4 +860,6 @@ varFree(Variant *this)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -57,7 +57,6 @@ String *varStr(const Variant *this);
String *varStrForce(const Variant *this); String *varStrForce(const Variant *this);
Variant *varNewVarLst(const VariantList *data); Variant *varNewVarLst(const VariantList *data);
Variant *varNewVarLstEmpty();
VariantList *varVarLst(const Variant *this); VariantList *varVarLst(const Variant *this);
Variant *varDup(const Variant *this); Variant *varDup(const Variant *this);
@@ -66,4 +65,19 @@ VariantType varType(const Variant *this);
void varFree(Variant *this); void varFree(Variant *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t varToLog(const Variant *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_CONST_VARIANT_TYPE \
const FUNCTION_DEBUG_VARIANT_TYPE
#define FUNCTION_DEBUG_CONST_VARIANT_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_VARIANT_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_VARIANT_TYPE \
Variant *
#define FUNCTION_DEBUG_VARIANT_FORMAT(value, buffer, bufferSize) \
varToLog(value, buffer, bufferSize)
#endif #endif

View File

@@ -5,6 +5,7 @@ Variant List Handler
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/type/list.h" #include "common/type/list.h"
#include "common/type/variantList.h" #include "common/type/variantList.h"
@@ -15,7 +16,8 @@ Wrapper for lstNew()
VariantList * VariantList *
varLstNew() varLstNew()
{ {
return (VariantList *)lstNew(sizeof(Variant *)); FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(VARIANT_LIST, (VariantList *)lstNew(sizeof(Variant *)));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -24,6 +26,10 @@ Create a variant list from a string list
VariantList * VariantList *
varLstNewStrLst(const StringList *stringList) varLstNewStrLst(const StringList *stringList)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, stringList);
FUNCTION_TEST_END();
VariantList *result = NULL; VariantList *result = NULL;
if (stringList != NULL) if (stringList != NULL)
@@ -34,7 +40,7 @@ varLstNewStrLst(const StringList *stringList)
varLstAdd(result, varNewStr(strLstGet(stringList, listIdx))); varLstAdd(result, varNewStr(strLstGet(stringList, listIdx)));
} }
return result; FUNCTION_TEST_RESULT(VARIANT_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -43,6 +49,10 @@ Duplicate a variant list
VariantList * VariantList *
varLstDup(const VariantList *source) varLstDup(const VariantList *source)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, source);
FUNCTION_TEST_END();
VariantList *result = NULL; VariantList *result = NULL;
if (source != NULL) if (source != NULL)
@@ -53,7 +63,7 @@ varLstDup(const VariantList *source)
varLstAdd(result, varDup(varLstGet(source, listIdx))); varLstAdd(result, varDup(varLstGet(source, listIdx)));
} }
return result; FUNCTION_TEST_RESULT(VARIANT_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -62,7 +72,14 @@ Wrapper for lstAdd()
VariantList * VariantList *
varLstAdd(VariantList *this, Variant *data) varLstAdd(VariantList *this, Variant *data)
{ {
return (VariantList *)lstAdd((List *)this, &data); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
FUNCTION_TEST_PARAM(VARIANT, data);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT_LIST, (VariantList *)lstAdd((List *)this, &data));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -71,7 +88,14 @@ Wrapper for lstGet()
Variant * Variant *
varLstGet(const VariantList *this, unsigned int listIdx) varLstGet(const VariantList *this, unsigned int listIdx)
{ {
return *(Variant **)lstGet((List *)this, listIdx); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
FUNCTION_TEST_PARAM(UINT, listIdx);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, *(Variant **)lstGet((List *)this, listIdx));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -80,7 +104,13 @@ Wrapper for lstSize()
unsigned int unsigned int
varLstSize(const VariantList *this) varLstSize(const VariantList *this)
{ {
return lstSize((List *)this); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, lstSize((List *)this));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -89,5 +119,11 @@ Wrapper for lstFree()
void void
varLstFree(VariantList *this) varLstFree(VariantList *this)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
FUNCTION_TEST_END();
lstFree((List *)this); lstFree((List *)this);
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -23,4 +23,12 @@ Variant *varLstGet(const VariantList *this, unsigned int listIdx);
unsigned int varLstSize(const VariantList *this); unsigned int varLstSize(const VariantList *this);
void varLstFree(VariantList *this); void varLstFree(VariantList *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_VARIANT_LIST_TYPE \
VariantList *
#define FUNCTION_DEBUG_VARIANT_LIST_FORMAT(value, buffer, bufferSize) \
objToLog(value, "VariantList", buffer, bufferSize)
#endif #endif

View File

@@ -1,6 +1,7 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Wait Handler Wait Handler
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/time.h" #include "common/time.h"
#include "common/wait.h" #include "common/wait.h"
@@ -23,9 +24,11 @@ New wait handler
Wait * Wait *
waitNew(double waitTime) waitNew(double waitTime)
{ {
// Make sure wait time is valid FUNCTION_DEBUG_BEGIN(logLevelTrace);
if (waitTime < 0.1 || waitTime > 999999.0) FUNCTION_DEBUG_PARAM(DOUBLE, waitTime);
THROW(AssertError, "waitTime must be >= 0.1 and <= 999999.0");
FUNCTION_DEBUG_ASSERT(waitTime >= 0.1 && waitTime <= 999999.0);
FUNCTION_DEBUG_END();
// Allocate wait object // Allocate wait object
Wait *this = NULL; Wait *this = NULL;
@@ -51,7 +54,7 @@ waitNew(double waitTime)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(WAIT, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -60,6 +63,12 @@ Wait and return whether the caller has more time left
bool bool
waitMore(Wait *this) waitMore(Wait *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(WAIT, this);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
// If sleep is 0 then the wait time has already ended // If sleep is 0 then the wait time has already ended
@@ -93,7 +102,7 @@ waitMore(Wait *this)
result = true; result = true;
} }
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -102,6 +111,12 @@ Free the wait
void void
waitFree(Wait *this) waitFree(Wait *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(WAIT, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -16,4 +16,12 @@ Wait *waitNew(double waitTime);
bool waitMore(Wait *this); bool waitMore(Wait *this);
void waitFree(Wait *this); void waitFree(Wait *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_WAIT_TYPE \
Wait *
#define FUNCTION_DEBUG_WAIT_FORMAT(value, buffer, bufferSize) \
objToLog(value, "Wait", buffer, bufferSize)
#endif #endif

View File

@@ -4,6 +4,7 @@ Command and Option Configuration
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
@@ -71,39 +72,32 @@ Include the automatically generated configuration data
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "config/config.auto.c" #include "config/config.auto.c"
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
// The command must be set
#define ASSERT_DEBUG_COMMAND_SET() \
ASSERT_DEBUG(cfgCommand() != cfgCmdNone)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Store the config memory context Store the config memory context
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
MemContext *configMemContext = NULL; static MemContext *configMemContext = NULL;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Store the current command Store the current command
This is generally set by the command parser but can also be set by during execute to change commands, i.e. backup -> expire. This is generally set by the command parser but can also be set by during execute to change commands, i.e. backup -> expire.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
ConfigCommand command = cfgCmdNone; static ConfigCommand command = cfgCmdNone;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Store the location of the executable Store the location of the executable
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
String *exe = NULL; static String *exe = NULL;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Was help requested for the command? Was help requested for the command?
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
bool help = false; static bool help = false;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Store the list of parameters passed to the command Store the list of parameters passed to the command
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
StringList *paramList = NULL; static StringList *paramList = NULL;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Map options names and indexes to option definitions. Map options names and indexes to option definitions.
@@ -127,6 +121,8 @@ Initialize or reinitialize the configuration data
void void
cfgInit() cfgInit()
{ {
FUNCTION_TEST_VOID();
// Reset configuration // Reset configuration
command = cfgCmdNone; command = cfgCmdNone;
exe = NULL; exe = NULL;
@@ -151,34 +147,32 @@ cfgInit()
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get the current command Get/set the current command
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
ConfigCommand ConfigCommand
cfgCommand() cfgCommand()
{ {
return command; FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(ENUM, command);
} }
/***********************************************************************************************************************************
Set the current command
***********************************************************************************************************************************/
void void
cfgCommandSet(ConfigCommand commandParam) cfgCommandSet(ConfigCommand commandParam)
{ {
command = commandParam; FUNCTION_TEST_BEGIN();
} FUNCTION_TEST_PARAM(ENUM, commandParam);
/*********************************************************************************************************************************** FUNCTION_TEST_ASSERT(commandParam <= cfgCmdNone);
Ensure that command id is valid FUNCTION_TEST_END();
***********************************************************************************************************************************/
void command = commandParam;
cfgCommandCheck(ConfigCommand commandId)
{ FUNCTION_TEST_RESULT_VOID();
if (commandId >= CFG_COMMAND_TOTAL)
THROW_FMT(AssertError, "command id %u invalid - must be >= 0 and < %d", commandId, CFG_COMMAND_TOTAL);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -187,13 +181,20 @@ Was help requested?
bool bool
cfgCommandHelp() cfgCommandHelp()
{ {
return help; FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(BOOL, help);
} }
void void
cfgCommandHelpSet(bool helpParam) cfgCommandHelpSet(bool helpParam)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BOOL, helpParam);
FUNCTION_TEST_END();
help = helpParam; help = helpParam;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -205,16 +206,27 @@ be modified to do the mapping.
ConfigDefineCommand ConfigDefineCommand
cfgCommandDefIdFromId(ConfigCommand commandId) cfgCommandDefIdFromId(ConfigCommand commandId)
{ {
cfgCommandCheck(commandId); FUNCTION_TEST_BEGIN();
return (ConfigDefineCommand)commandId; FUNCTION_TEST_PARAM(ENUM, commandId);
FUNCTION_TEST_ASSERT(commandId < cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, (ConfigDefineCommand)commandId);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get command id by name Get command id by name
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
int ConfigCommand
cfgCommandId(const char *commandName) cfgCommandId(const char *commandName)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, commandName);
FUNCTION_TEST_ASSERT(commandName != NULL);
FUNCTION_TEST_END();
ConfigCommand commandId; ConfigCommand commandId;
for (commandId = 0; commandId < cfgCmdNone; commandId++) for (commandId = 0; commandId < cfgCmdNone; commandId++)
@@ -224,7 +236,7 @@ cfgCommandId(const char *commandName)
if (commandId == cfgCmdNone) if (commandId == cfgCmdNone)
THROW_FMT(AssertError, "invalid command '%s'", commandName); THROW_FMT(AssertError, "invalid command '%s'", commandName);
return commandId; FUNCTION_TEST_RESULT(ENUM, commandId);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -233,8 +245,13 @@ Get command name by id
const char * const char *
cfgCommandName(ConfigCommand commandId) cfgCommandName(ConfigCommand commandId)
{ {
cfgCommandCheck(commandId); FUNCTION_TEST_BEGIN();
return configCommandData[commandId].name; FUNCTION_TEST_PARAM(ENUM, commandId);
FUNCTION_TEST_ASSERT(commandId < cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configCommandData[commandId].name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -243,6 +260,8 @@ Command parameters, if any
const StringList * const StringList *
cfgCommandParam() cfgCommandParam()
{ {
FUNCTION_TEST_VOID();
if (paramList == NULL) if (paramList == NULL)
{ {
MEM_CONTEXT_BEGIN(configMemContext) MEM_CONTEXT_BEGIN(configMemContext)
@@ -252,17 +271,25 @@ cfgCommandParam()
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
return paramList; FUNCTION_TEST_RESULT(STRING_LIST, paramList);
} }
void void
cfgCommandParamSet(const StringList *param) cfgCommandParamSet(const StringList *param)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING_LIST, param);
FUNCTION_TEST_ASSERT(param != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(configMemContext) MEM_CONTEXT_BEGIN(configMemContext)
{ {
paramList = strLstDup(param); paramList = strLstDup(param);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -271,17 +298,26 @@ Command parameters, if any
const String * const String *
cfgExe() cfgExe()
{ {
return exe; FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(STRING, exe);
} }
void void
cfgExeSet(const String *exeParam) cfgExeSet(const String *exeParam)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, exeParam);
FUNCTION_TEST_ASSERT(exeParam != NULL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(configMemContext) MEM_CONTEXT_BEGIN(configMemContext)
{ {
exe = strDup(exeParam); exe = strDup(exeParam);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -290,8 +326,11 @@ Does this command require an immediate lock?
bool bool
cfgLockRequired() cfgLockRequired()
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_TEST_BEGIN();
return configCommandData[cfgCommand()].lockRequired; FUNCTION_TEST_ASSERT(command != cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configCommandData[cfgCommand()].lockRequired);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -300,8 +339,11 @@ Get the lock type required for this command
LockType LockType
cfgLockType() cfgLockType()
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_TEST_BEGIN();
return (LockType)configCommandData[cfgCommand()].lockType; FUNCTION_TEST_ASSERT(command != cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, (LockType)configCommandData[cfgCommand()].lockType);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -310,8 +352,11 @@ Does this command log to a file?
bool bool
cfgLogFile() cfgLogFile()
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_TEST_BEGIN();
return configCommandData[cfgCommand()].logFile; FUNCTION_TEST_ASSERT(command != cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configCommandData[cfgCommand()].logFile);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -320,8 +365,11 @@ Get default log level -- used for log messages that are common to all commands
LogLevel LogLevel
cfgLogLevelDefault() cfgLogLevelDefault()
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_TEST_BEGIN();
return (LogLevel)configCommandData[cfgCommand()].logLevelDefault; FUNCTION_TEST_ASSERT(command != cfgCmdNone);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, (LogLevel)configCommandData[cfgCommand()].logLevelDefault);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -330,18 +378,11 @@ Get max stderr log level -- used to suppress error output for higher log levels,
LogLevel LogLevel
cfgLogLevelStdErrMax() cfgLogLevelStdErrMax()
{ {
ASSERT_DEBUG_COMMAND_SET(); FUNCTION_TEST_BEGIN();
return (LogLevel)configCommandData[cfgCommand()].logLevelStdErrMax; FUNCTION_TEST_ASSERT(command != cfgCmdNone);
} FUNCTION_TEST_END();
/*********************************************************************************************************************************** FUNCTION_TEST_RESULT(ENUM, (LogLevel)configCommandData[cfgCommand()].logLevelStdErrMax);
Ensure that option id is valid
***********************************************************************************************************************************/
void
cfgOptionCheck(ConfigOption optionId)
{
if (optionId >= CFG_OPTION_TOTAL)
THROW_FMT(AssertError, "option id %u invalid - must be >= 0 and < %d", optionId, CFG_OPTION_TOTAL);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -350,8 +391,13 @@ Get the option define for this option
ConfigDefineOption ConfigDefineOption
cfgOptionDefIdFromId(ConfigOption optionId) cfgOptionDefIdFromId(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionData[optionId].defineId; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, configOptionData[optionId].defineId);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -360,7 +406,11 @@ Get/set option default
const Variant * const Variant *
cfgOptionDefault(ConfigOption optionId) cfgOptionDefault(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
if (configOptionValue[optionId].defaultValue == NULL) if (configOptionValue[optionId].defaultValue == NULL)
{ {
@@ -410,12 +460,19 @@ cfgOptionDefault(ConfigOption optionId)
} }
} }
return configOptionValue[optionId].defaultValue; FUNCTION_TEST_RESULT(VARIANT, configOptionValue[optionId].defaultValue);
} }
void void
cfgOptionDefaultSet(ConfigOption optionId, const Variant *defaultValue) cfgOptionDefaultSet(ConfigOption optionId, const Variant *defaultValue)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(VARIANT, defaultValue);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(configMemContext) MEM_CONTEXT_BEGIN(configMemContext)
{ {
if (configOptionValue[optionId].defaultValue != NULL) if (configOptionValue[optionId].defaultValue != NULL)
@@ -432,6 +489,8 @@ cfgOptionDefaultSet(ConfigOption optionId, const Variant *defaultValue)
} }
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -440,8 +499,13 @@ Get index for option
unsigned int unsigned int
cfgOptionIndex(ConfigOption optionId) cfgOptionIndex(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionData[optionId].index; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, configOptionData[optionId].index);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -450,11 +514,19 @@ Get option id by name
int int
cfgOptionId(const char *optionName) cfgOptionId(const char *optionName)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, optionName);
FUNCTION_TEST_ASSERT(optionName != NULL);
FUNCTION_TEST_END();
int result = -1;
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++) for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
if (strcmp(optionName, configOptionData[optionId].name) == 0) if (strcmp(optionName, configOptionData[optionId].name) == 0)
return optionId; result = optionId;
return -1; FUNCTION_TEST_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -463,8 +535,13 @@ Get total indexed values for option
unsigned int unsigned int
cfgOptionIndexTotal(ConfigOption optionId) cfgOptionIndexTotal(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return cfgDefOptionIndexTotal(configOptionData[optionId].defineId); FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, cfgDefOptionIndexTotal(configOptionData[optionId].defineId));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -473,19 +550,26 @@ Get the id for this option define
ConfigOption ConfigOption
cfgOptionIdFromDefId(ConfigDefineOption optionDefId, unsigned int index) cfgOptionIdFromDefId(ConfigDefineOption optionDefId, unsigned int index)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(UINT, index);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(index < cfgDefOptionIndexTotal(optionDefId));
FUNCTION_TEST_END();
// Search for the option // Search for the option
ConfigOption optionId; ConfigOption optionId;
for (optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++) for (optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++) // {uncoverable - only a bug in code gen lets this loop end}
if (configOptionData[optionId].defineId == optionDefId) if (configOptionData[optionId].defineId == optionDefId)
break; break;
// Error when not found // If the mapping is not found then there is a bug in the code generator
if (optionId == CFG_OPTION_TOTAL) ASSERT_DEBUG(optionId != CFG_OPTION_TOTAL);
cfgDefOptionCheck(optionDefId);
// Return with original index // Return with original index
return optionId + index; FUNCTION_TEST_RESULT(ENUM, optionId + index);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -494,8 +578,13 @@ Get option name by id
const char * const char *
cfgOptionName(ConfigOption optionId) cfgOptionName(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionData[optionId].name; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configOptionData[optionId].name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -504,15 +593,28 @@ Was the option negated?
bool bool
cfgOptionNegate(ConfigOption optionId) cfgOptionNegate(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionValue[optionId].negate; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configOptionValue[optionId].negate);
} }
void void
cfgOptionNegateSet(ConfigOption optionId, bool negate) cfgOptionNegateSet(ConfigOption optionId, bool negate)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(BOOL, negate);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
configOptionValue[optionId].negate = negate; configOptionValue[optionId].negate = negate;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -521,15 +623,28 @@ Was the option reset?
bool bool
cfgOptionReset(ConfigOption optionId) cfgOptionReset(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionValue[optionId].reset; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configOptionValue[optionId].reset);
} }
void void
cfgOptionResetSet(ConfigOption optionId, bool reset) cfgOptionResetSet(ConfigOption optionId, bool reset)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(BOOL, reset);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
configOptionValue[optionId].reset = reset; configOptionValue[optionId].reset = reset;
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -538,69 +653,90 @@ Get and set config options
const Variant * const Variant *
cfgOption(ConfigOption optionId) cfgOption(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionValue[optionId].value; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(VARIANT, configOptionValue[optionId].value);
} }
bool bool
cfgOptionBool(ConfigOption optionId) cfgOptionBool(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
if (varType(configOptionValue[optionId].value) != varTypeBool) FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option '%s' is not type 'bool'", cfgOptionName(optionId)); FUNCTION_DEBUG_ASSERT(varType(configOptionValue[optionId].value) == varTypeBool);
FUNCTION_DEBUG_END();
return varBool(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(BOOL, varBool(configOptionValue[optionId].value));
} }
double double
cfgOptionDbl(ConfigOption optionId) cfgOptionDbl(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
if (varType(configOptionValue[optionId].value) != varTypeDouble) FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option '%s' is not type 'double'", cfgOptionName(optionId)); FUNCTION_DEBUG_ASSERT(varType(configOptionValue[optionId].value) == varTypeDouble);
FUNCTION_DEBUG_END();
return varDbl(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(DOUBLE, varDbl(configOptionValue[optionId].value));
} }
int int
cfgOptionInt(ConfigOption optionId) cfgOptionInt(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
if (varType(configOptionValue[optionId].value) != varTypeInt64) FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId)); FUNCTION_DEBUG_ASSERT(varType(configOptionValue[optionId].value) == varTypeInt64);
FUNCTION_DEBUG_END();
return varIntForce(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(INT, varIntForce(configOptionValue[optionId].value));
} }
int64_t int64_t
cfgOptionInt64(ConfigOption optionId) cfgOptionInt64(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
if (varType(configOptionValue[optionId].value) != varTypeInt64) FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId)); FUNCTION_DEBUG_ASSERT(varType(configOptionValue[optionId].value) == varTypeInt64);
FUNCTION_DEBUG_END();
return varInt64(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(INT64, varInt64(configOptionValue[optionId].value));
} }
const KeyValue * const KeyValue *
cfgOptionKv(ConfigOption optionId) cfgOptionKv(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
if (varType(configOptionValue[optionId].value) != varTypeKeyValue) FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option '%s' is not type 'KeyValue'", cfgOptionName(optionId)); FUNCTION_DEBUG_ASSERT(varType(configOptionValue[optionId].value) == varTypeKeyValue);
FUNCTION_DEBUG_END();
return varKv(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(KEY_VALUE, varKv(configOptionValue[optionId].value));
} }
const VariantList * const VariantList *
cfgOptionLst(ConfigOption optionId) cfgOptionLst(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_DEBUG_ASSERT(
configOptionValue[optionId].value == NULL || varType(configOptionValue[optionId].value) == varTypeVariantList);
FUNCTION_DEBUG_END();
if (configOptionValue[optionId].value == NULL) if (configOptionValue[optionId].value == NULL)
{ {
@@ -610,34 +746,39 @@ cfgOptionLst(ConfigOption optionId)
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
else if (varType(configOptionValue[optionId].value) != varTypeVariantList)
THROW_FMT(AssertError, "option '%s' is not type 'VariantList'", cfgOptionName(optionId));
return varVarLst(configOptionValue[optionId].value); FUNCTION_DEBUG_RESULT(VARIANT_LIST, varVarLst(configOptionValue[optionId].value));
} }
const String * const String *
cfgOptionStr(ConfigOption optionId) cfgOptionStr(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(ENUM, optionId);
FUNCTION_DEBUG_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_DEBUG_ASSERT(
configOptionValue[optionId].value == NULL || varType(configOptionValue[optionId].value) == varTypeString);
FUNCTION_DEBUG_END();
const String *result = NULL; const String *result = NULL;
if (configOptionValue[optionId].value != NULL) if (configOptionValue[optionId].value != NULL)
{
if (varType(configOptionValue[optionId].value) != varTypeString)
THROW_FMT(AssertError, "option '%s' is not type 'String'", cfgOptionName(optionId));
result = varStr(configOptionValue[optionId].value); result = varStr(configOptionValue[optionId].value);
}
return result; FUNCTION_DEBUG_RESULT(CONST_STRING, result);
} }
void void
cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value) cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(ENUM, source);
FUNCTION_TEST_PARAM(VARIANT, value);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
MEM_CONTEXT_BEGIN(configMemContext) MEM_CONTEXT_BEGIN(configMemContext)
{ {
@@ -720,6 +861,8 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
varFree(valueOld); varFree(valueOld);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -728,8 +871,13 @@ How was the option set (default, param, config)?
ConfigSource ConfigSource
cfgOptionSource(ConfigOption optionId) cfgOptionSource(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionValue[optionId].source; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, configOptionValue[optionId].source);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -738,8 +886,13 @@ Is the option valid for the command and set?
bool bool
cfgOptionTest(ConfigOption optionId) cfgOptionTest(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return cfgOptionValid(optionId) && configOptionValue[optionId].value != NULL; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, cfgOptionValid(optionId) && configOptionValue[optionId].value != NULL);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -748,13 +901,26 @@ Is the option valid for this command?
bool bool
cfgOptionValid(ConfigOption optionId) cfgOptionValid(ConfigOption optionId)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
return configOptionValue[optionId].valid; FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configOptionValue[optionId].valid);
} }
void void
cfgOptionValidSet(ConfigOption optionId, bool valid) cfgOptionValidSet(ConfigOption optionId, bool valid)
{ {
cfgOptionCheck(optionId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_PARAM(BOOL, valid);
FUNCTION_TEST_ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_END();
configOptionValue[optionId].valid = valid; configOptionValue[optionId].valid = valid;
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -86,7 +86,7 @@ void cfgInit();
ConfigDefineCommand cfgCommandDefIdFromId(ConfigCommand commandId); ConfigDefineCommand cfgCommandDefIdFromId(ConfigCommand commandId);
bool cfgCommandHelp(); bool cfgCommandHelp();
void cfgCommandHelpSet(bool helpParam); void cfgCommandHelpSet(bool helpParam);
int cfgCommandId(const char *commandName); ConfigCommand cfgCommandId(const char *commandName);
void cfgCommandParamSet(const StringList *param); void cfgCommandParamSet(const StringList *param);
void cfgCommandSet(ConfigCommand commandParam); void cfgCommandSet(ConfigCommand commandParam);

View File

@@ -6,6 +6,7 @@ Command and Option Configuration Definition
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "config/define.h" #include "config/define.h"
@@ -180,6 +181,21 @@ cfgDefDataFind(
ConfigDefineDataType typeFind, ConfigDefineCommand commandDefId, const void **dataList, bool *dataDefFound, int *dataDef, ConfigDefineDataType typeFind, ConfigDefineCommand commandDefId, const void **dataList, bool *dataDefFound, int *dataDef,
const void ***dataDefList, unsigned int *dataDefListSize) const void ***dataDefList, unsigned int *dataDefListSize)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, typeFind);
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(VOIDPP, dataList);
FUNCTION_TEST_PARAM(BOOLP, dataDefFound);
FUNCTION_TEST_PARAM(INTP, dataDef);
FUNCTION_TEST_PARAM(VOIDPP, dataDefList);
FUNCTION_TEST_PARAM(VOIDPP, dataDefListSize);
FUNCTION_TEST_ASSERT(dataDefFound != NULL);
FUNCTION_TEST_ASSERT(dataDef != NULL);
FUNCTION_TEST_ASSERT(dataDefList != NULL);
FUNCTION_TEST_ASSERT(dataDefListSize != NULL);
FUNCTION_TEST_END();
*dataDefFound = false; *dataDefFound = false;
// Only proceed if there is data // Only proceed if there is data
@@ -227,6 +243,8 @@ cfgDefDataFind(
} }
while(type != configDefDataTypeEnd); while(type != configDefDataTypeEnd);
} }
FUNCTION_TEST_RESULT_VOID();
} }
#define CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, type) \ #define CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, type) \
@@ -244,37 +262,15 @@ Command and option define totals
unsigned int unsigned int
cfgDefCommandTotal() cfgDefCommandTotal()
{ {
return sizeof(configDefineCommandData) / sizeof(ConfigDefineCommandData); FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(UINT, sizeof(configDefineCommandData) / sizeof(ConfigDefineCommandData));
} }
unsigned int unsigned int
cfgDefOptionTotal() cfgDefOptionTotal()
{ {
return sizeof(configDefineOptionData) / sizeof(ConfigDefineOptionData); FUNCTION_TEST_VOID();
} FUNCTION_TEST_RESULT(UINT, sizeof(configDefineOptionData) / sizeof(ConfigDefineOptionData));
/***********************************************************************************************************************************
Check that command and option ids are valid
***********************************************************************************************************************************/
void
cfgDefCommandCheck(ConfigDefineCommand commandDefId)
{
if (commandDefId >= cfgDefCommandTotal())
THROW_FMT(AssertError, "command def id %u invalid - must be >= 0 and < %u", commandDefId, cfgDefCommandTotal());
}
void
cfgDefOptionCheck(ConfigDefineOption optionDefId)
{
if (optionDefId >= cfgDefOptionTotal())
THROW_FMT(AssertError, "option def id %u invalid - must be >= 0 and < %u", optionDefId, cfgDefOptionTotal());
}
static void
cfgDefCommandOptionCheck(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{
cfgDefCommandCheck(commandDefId);
cfgDefOptionCheck(optionDefId);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -283,8 +279,13 @@ Command help description
const char * const char *
cfgDefCommandHelpDescription(ConfigDefineCommand commandDefId) cfgDefCommandHelpDescription(ConfigDefineCommand commandDefId)
{ {
cfgDefCommandCheck(commandDefId); FUNCTION_TEST_BEGIN();
return configDefineCommandData[commandDefId].helpDescription; FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configDefineCommandData[commandDefId].helpDescription);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -293,8 +294,13 @@ Command help summary
const char * const char *
cfgDefCommandHelpSummary(ConfigDefineCommand commandDefId) cfgDefCommandHelpSummary(ConfigDefineCommand commandDefId)
{ {
cfgDefCommandCheck(commandDefId); FUNCTION_TEST_BEGIN();
return configDefineCommandData[commandDefId].helpSummary; FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configDefineCommandData[commandDefId].helpSummary);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -303,47 +309,76 @@ Option allow lists
bool bool
cfgDefOptionAllowList(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionAllowList(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList);
return dataDefFound; FUNCTION_TEST_RESULT(BOOL, dataDefFound);
} }
const char * const char *
cfgDefOptionAllowListValue(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, unsigned int valueId) cfgDefOptionAllowListValue(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, unsigned int valueId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(UINT, valueId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(valueId < cfgDefOptionAllowListValueTotal(commandDefId, optionDefId));
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList);
if (valueId >= dataDefListSize) FUNCTION_TEST_RESULT(STRINGZ, (char *)dataDefList[valueId]);
THROW_FMT(AssertError, "value id %u invalid - must be >= 0 and < %u", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
} }
unsigned int unsigned int
cfgDefOptionAllowListValueTotal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionAllowListValueTotal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList);
return dataDefListSize; FUNCTION_TEST_RESULT(UINT, dataDefListSize);
} }
// Check if the value matches a value in the allow list // Check if the value matches a value in the allow list
bool bool
cfgDefOptionAllowListValueValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, const char *value) cfgDefOptionAllowListValueValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, const char *value)
{ {
ASSERT_DEBUG(value != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(STRINGZ, value);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
bool result = false;
for (unsigned int valueIdx = 0; valueIdx < cfgDefOptionAllowListValueTotal(commandDefId, optionDefId); valueIdx++) for (unsigned int valueIdx = 0; valueIdx < cfgDefOptionAllowListValueTotal(commandDefId, optionDefId); valueIdx++)
{
if (strcmp(value, cfgDefOptionAllowListValue(commandDefId, optionDefId, valueIdx)) == 0) if (strcmp(value, cfgDefOptionAllowListValue(commandDefId, optionDefId, valueIdx)) == 0)
return true; result = true;
}
return false; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -352,31 +387,51 @@ Allow range
bool bool
cfgDefOptionAllowRange(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionAllowRange(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange);
return dataDefFound; FUNCTION_TEST_RESULT(BOOL, dataDefFound);
} }
double double
cfgDefOptionAllowRangeMax(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionAllowRangeMax(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange);
return ((double)(((int64_t)(intptr_t)dataDefList[2]) + (((int64_t)(intptr_t)dataDefList[3]) * 1000000000L))) / 100; FUNCTION_TEST_RESULT(
DOUBLE, ((double)(((int64_t)(intptr_t)dataDefList[2]) + (((int64_t)(intptr_t)dataDefList[3]) * 1000000000L))) / 100);
} }
double double
cfgDefOptionAllowRangeMin(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionAllowRangeMin(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowRange);
return ((double)(((int64_t)(intptr_t)dataDefList[0]) + (((int64_t)(intptr_t)dataDefList[1]) * 1000000000L))) / 100; FUNCTION_TEST_RESULT(
DOUBLE, ((double)(((int64_t)(intptr_t)dataDefList[0]) + (((int64_t)(intptr_t)dataDefList[1]) * 1000000000L))) / 100);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -385,14 +440,22 @@ Default value for the option
const char * const char *
cfgDefOptionDefault(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionDefault(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDefault); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDefault);
if (dataDefFound) char *result = NULL;
return (char *)dataDefList[0];
return NULL; if (dataDefFound)
result = (char *)dataDefList[0];
FUNCTION_TEST_RESULT(STRINGZ, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -401,57 +464,92 @@ Dependencies and depend lists
bool bool
cfgDefOptionDepend(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionDepend(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
return dataDefFound; FUNCTION_TEST_RESULT(BOOL, dataDefFound);
} }
ConfigDefineOption ConfigDefineOption
cfgDefOptionDependOption(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionDependOption(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
return (ConfigDefineOption)dataDef; FUNCTION_TEST_RESULT(ENUM, (ConfigDefineOption)dataDef);
} }
const char * const char *
cfgDefOptionDependValue(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, unsigned int valueId) cfgDefOptionDependValue(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, unsigned int valueId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(UINT, valueId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(valueId < cfgDefOptionDependValueTotal(commandDefId, optionDefId));
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
if (valueId >= dataDefListSize) FUNCTION_TEST_RESULT(STRINGZ, (char *)dataDefList[valueId]);
THROW_FMT(AssertError, "value id %u invalid - must be >= 0 and < %u", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
} }
unsigned int unsigned int
cfgDefOptionDependValueTotal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionDependValueTotal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
return dataDefListSize; FUNCTION_TEST_RESULT(UINT, dataDefListSize);
} }
// Check if the value matches a value in the allow list // Check if the value matches a value in the allow list
bool bool
cfgDefOptionDependValueValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, const char *value) cfgDefOptionDependValueValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId, const char *value)
{ {
ASSERT_DEBUG(value != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(STRINGZ, value);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(value != NULL);
FUNCTION_TEST_END();
bool result = false;
for (unsigned int valueIdx = 0; valueIdx < cfgDefOptionDependValueTotal(commandDefId, optionDefId); valueIdx++) for (unsigned int valueIdx = 0; valueIdx < cfgDefOptionDependValueTotal(commandDefId, optionDefId); valueIdx++)
{
if (strcmp(value, cfgDefOptionDependValue(commandDefId, optionDefId, valueIdx)) == 0) if (strcmp(value, cfgDefOptionDependValue(commandDefId, optionDefId, valueIdx)) == 0)
return true; result = true;
}
return false; FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -460,14 +558,22 @@ Option help description
const char * const char *
cfgDefOptionHelpDescription(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionHelpDescription(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeHelpDescription); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeHelpDescription);
if (dataDefFound) const char *result = configDefineOptionData[optionDefId].helpDescription;
return (char *)dataDefList[0];
return configDefineOptionData[optionDefId].helpDescription; if (dataDefFound)
result = (char *)dataDefList[0];
FUNCTION_TEST_RESULT(STRINGZ, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -476,34 +582,45 @@ Option help name alt
bool bool
cfgDefOptionHelpNameAlt(ConfigDefineOption optionDefId) cfgDefOptionHelpNameAlt(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt); CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt);
return dataDefFound; FUNCTION_TEST_RESULT(BOOL, dataDefFound);
} }
const char * const char *
cfgDefOptionHelpNameAltValue(ConfigDefineOption optionDefId, unsigned int valueId) cfgDefOptionHelpNameAltValue(ConfigDefineOption optionDefId, unsigned int valueId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_PARAM(UINT, valueId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_ASSERT(valueId < cfgDefOptionHelpNameAltValueTotal(optionDefId));
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt); CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt);
if (valueId >= dataDefListSize) FUNCTION_TEST_RESULT(STRINGZ, (char *)dataDefList[valueId]);
THROW_FMT(AssertError, "value id %u invalid - must be >= 0 and < %u", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
} }
unsigned int unsigned int
cfgDefOptionHelpNameAltValueTotal(ConfigDefineOption optionDefId) cfgDefOptionHelpNameAltValueTotal(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt); CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt);
return dataDefListSize; FUNCTION_TEST_RESULT(UINT, dataDefListSize);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -512,8 +629,13 @@ Option help section
const char * const char *
cfgDefOptionHelpSection(ConfigDefineOption optionDefId) cfgDefOptionHelpSection(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].helpSection; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configDefineOptionData[optionDefId].helpSection);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -522,14 +644,22 @@ Option help summary
const char * const char *
cfgDefOptionHelpSummary(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionHelpSummary(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeHelpSummary); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeHelpSummary);
if (dataDefFound) const char *result = configDefineOptionData[optionDefId].helpSummary;
return (char *)dataDefList[0];
return configDefineOptionData[optionDefId].helpSummary; if (dataDefFound)
result = (char *)dataDefList[0];
FUNCTION_TEST_RESULT(STRINGZ, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -538,11 +668,19 @@ Get option id by name
int int
cfgDefOptionId(const char *optionName) cfgDefOptionId(const char *optionName)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRINGZ, optionName);
FUNCTION_TEST_ASSERT(optionName != NULL);
FUNCTION_TEST_END();
int result = -1;
for (ConfigDefineOption optionDefId = 0; optionDefId < cfgDefOptionTotal(); optionDefId++) for (ConfigDefineOption optionDefId = 0; optionDefId < cfgDefOptionTotal(); optionDefId++)
if (strcmp(optionName, configDefineOptionData[optionDefId].name) == 0) if (strcmp(optionName, configDefineOptionData[optionDefId].name) == 0)
return optionDefId; result = optionDefId;
return -1; FUNCTION_TEST_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -551,8 +689,13 @@ Get total indexed values for option
unsigned int unsigned int
cfgDefOptionIndexTotal(ConfigDefineOption optionDefId) cfgDefOptionIndexTotal(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].indexTotal; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(UINT, configDefineOptionData[optionDefId].indexTotal);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -561,14 +704,22 @@ Is the option for internal use only?
bool bool
cfgDefOptionInternal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionInternal(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeInternal); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeInternal);
if (dataDefFound) bool result = configDefineOptionData[optionDefId].internal;
return (bool)dataDef;
return configDefineOptionData[optionDefId].internal; if (dataDefFound)
result = (bool)dataDef;
FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -577,8 +728,13 @@ Name of the option
const char * const char *
cfgDefOptionName(ConfigDefineOption optionDefId) cfgDefOptionName(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].name; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STRINGZ, configDefineOptionData[optionDefId].name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -587,14 +743,20 @@ Option prefix for indexed options
const char * const char *
cfgDefOptionPrefix(ConfigDefineOption optionDefId) cfgDefOptionPrefix(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypePrefix); CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypePrefix);
if (dataDefFound) char *result = NULL;
return (char *)dataDefList[0];
return NULL; if (dataDefFound)
result = (char *)dataDefList[0];
FUNCTION_TEST_RESULT(STRINGZ, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -603,8 +765,13 @@ Does the option need to be protected from showing up in logs, command lines, etc
bool bool
cfgDefOptionSecure(ConfigDefineOption optionDefId) cfgDefOptionSecure(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].secure; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configDefineOptionData[optionDefId].secure);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -613,14 +780,22 @@ Is the option required
bool bool
cfgDefOptionRequired(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionRequired(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeRequired); CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeRequired);
if (dataDefFound) bool result = configDefineOptionData[optionDefId].required;
return (bool)dataDef;
return configDefineOptionData[optionDefId].required; if (dataDefFound)
result = (bool)dataDef;
FUNCTION_TEST_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -629,8 +804,13 @@ Get option section
ConfigDefSection ConfigDefSection
cfgDefOptionSection(ConfigDefineOption optionDefId) cfgDefOptionSection(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].section; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(ENUM, configDefineOptionData[optionDefId].section);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -639,8 +819,13 @@ Get option data type
int int
cfgDefOptionType(ConfigDefineOption optionDefId) cfgDefOptionType(ConfigDefineOption optionDefId)
{ {
cfgDefOptionCheck(optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].type; FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(INT, configDefineOptionData[optionDefId].type);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -649,6 +834,13 @@ Is the option valid for the command?
bool bool
cfgDefOptionValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId) cfgDefOptionValid(ConfigDefineCommand commandDefId, ConfigDefineOption optionDefId)
{ {
cfgDefCommandOptionCheck(commandDefId, optionDefId); FUNCTION_TEST_BEGIN();
return configDefineOptionData[optionDefId].commandValid & (1 << commandDefId); FUNCTION_TEST_PARAM(ENUM, commandDefId);
FUNCTION_TEST_PARAM(ENUM, optionDefId);
FUNCTION_TEST_ASSERT(commandDefId < cfgDefCommandTotal());
FUNCTION_TEST_ASSERT(optionDefId < cfgDefOptionTotal());
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, configDefineOptionData[optionDefId].commandValid & (1 << commandDefId));
} }

View File

@@ -6,6 +6,7 @@ Configuration Load
#include "command/command.h" #include "command/command.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/debug.h"
#include "common/lock.h" #include "common/lock.h"
#include "common/log.h" #include "common/log.h"
#include "config/config.h" #include "config/config.h"
@@ -18,6 +19,8 @@ Load log settings
void void
cfgLoadLogSetting() cfgLoadLogSetting()
{ {
FUNCTION_DEBUG_VOID(logLevelTrace);
// Initialize logging // Initialize logging
LogLevel logLevelConsole = logLevelOff; LogLevel logLevelConsole = logLevelOff;
LogLevel logLevelStdErr = logLevelOff; LogLevel logLevelStdErr = logLevelOff;
@@ -43,6 +46,8 @@ cfgLoadLogSetting()
logTimestamp = cfgOptionBool(cfgOptLogTimestamp); logTimestamp = cfgOptionBool(cfgOptLogTimestamp);
logInit(logLevelConsole, logLevelStdErr, logLevelFile, logTimestamp); logInit(logLevelConsole, logLevelStdErr, logLevelFile, logTimestamp);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -51,6 +56,8 @@ Update options that have complex rules
void void
cfgLoadUpdateOption() cfgLoadUpdateOption()
{ {
FUNCTION_DEBUG_VOID(logLevelTrace);
// Set default for repo-host-cmd // Set default for repo-host-cmd
if (cfgOptionTest(cfgOptRepoHost) && cfgOptionSource(cfgOptRepoHostCmd) == cfgSourceDefault) if (cfgOptionTest(cfgOptRepoHost) && cfgOptionSource(cfgOptRepoHostCmd) == cfgSourceDefault)
cfgOptionDefaultSet(cfgOptRepoHostCmd, varNewStr(cfgExe())); cfgOptionDefaultSet(cfgOptRepoHostCmd, varNewStr(cfgExe()));
@@ -186,6 +193,8 @@ cfgLoadUpdateOption()
} }
} }
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -194,6 +203,11 @@ Load the configuration
void void
cfgLoad(unsigned int argListSize, const char *argList[]) cfgLoad(unsigned int argListSize, const char *argList[])
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(UINT, argListSize);
FUNCTION_DEBUG_PARAM(CHARPY, argList);
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
// Parse config from command line and config file // Parse config from command line and config file
@@ -209,12 +223,8 @@ cfgLoad(unsigned int argListSize, const char *argList[])
// If a command is set // If a command is set
if (cfgCommand() != cfgCmdNone) if (cfgCommand() != cfgCmdNone)
{ {
// Acquire a lock if required
if (cfgLockRequired())
lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, true);
// Open the log file if this command logs to a file // Open the log file if this command logs to a file
if (cfgLogFile()) if (cfgLogFile() && !cfgCommandHelp())
{ {
logFileSet( logFileSet(
strPtr(strNewFmt("%s/%s-%s.log", strPtr(cfgOptionStr(cfgOptLogPath)), strPtr(cfgOptionStr(cfgOptStanza)), strPtr(strNewFmt("%s/%s-%s.log", strPtr(cfgOptionStr(cfgOptLogPath)), strPtr(cfgOptionStr(cfgOptStanza)),
@@ -224,9 +234,15 @@ cfgLoad(unsigned int argListSize, const char *argList[])
// Begin the command // Begin the command
cmdBegin(true); cmdBegin(true);
// Open the log file if this command logs to a file
if (cfgLockRequired() && !cfgCommandHelp())
lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, true);
// Update options that have complex rules // Update options that have complex rules
cfgLoadUpdateOption(); cfgLoadUpdateOption();
} }
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -6,6 +6,7 @@ Command and Option Parse
#include <strings.h> #include <strings.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/ini.h" #include "common/ini.h"
#include "common/log.h" #include "common/log.h"
@@ -86,6 +87,13 @@ Convert the value passed into bytes and update valueDbl for range checking
void void
convertToByte(String **value, double *valueDbl) convertToByte(String **value, double *valueDbl)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRINGP, value);
FUNCTION_DEBUG_PARAM(DOUBLEP, valueDbl);
FUNCTION_DEBUG_ASSERT(valueDbl != NULL);
FUNCTION_DEBUG_END();
// Make a copy of the value so it is not updated until we know the conversion will succeed // Make a copy of the value so it is not updated until we know the conversion will succeed
String *result = strLower(strDup(*value)); String *result = strLower(strDup(*value));
@@ -161,6 +169,8 @@ convertToByte(String **value, double *valueDbl)
} }
else else
THROW_FMT(FormatError, "value '%s' is not valid", strPtr(*value)); THROW_FMT(FormatError, "value '%s' is not valid", strPtr(*value));
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -198,6 +208,18 @@ cfgFileLoad( // NOTE: Pas
const String *optConfigIncludePathDefault, // Current default for --config-include-path option const String *optConfigIncludePathDefault, // Current default for --config-include-path option
const String *origConfigDefault) // Original --config option default (/etc/pgbackrest.conf) const String *origConfigDefault) // Original --config option default (/etc/pgbackrest.conf)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM_PTR("ParseOption *", optionList);
FUNCTION_DEBUG_PARAM(STRING, optConfigDefault);
FUNCTION_DEBUG_PARAM(STRING, optConfigIncludePathDefault);
FUNCTION_DEBUG_PARAM(STRING, origConfigDefault);
FUNCTION_TEST_ASSERT(optionList != NULL);
FUNCTION_TEST_ASSERT(optConfigDefault != NULL);
FUNCTION_TEST_ASSERT(optConfigIncludePathDefault != NULL);
FUNCTION_TEST_ASSERT(origConfigDefault != NULL);
FUNCTION_DEBUG_END();
bool loadConfig = true; bool loadConfig = true;
bool loadConfigInclude = true; bool loadConfigInclude = true;
@@ -324,7 +346,7 @@ cfgFileLoad( // NOTE: Pas
} }
} }
return result; FUNCTION_DEBUG_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -336,6 +358,11 @@ logic to this critical path code.
void void
configParse(unsigned int argListSize, const char *argList[]) configParse(unsigned int argListSize, const char *argList[])
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(UINT, argListSize);
FUNCTION_DEBUG_PARAM(CHARPY, argList);
FUNCTION_DEBUG_END();
// Initialize configuration // Initialize configuration
cfgInit(); cfgInit();
@@ -406,17 +433,11 @@ configParse(unsigned int argListSize, const char *argList[])
// If the option is unknown then error // If the option is unknown then error
case '?': case '?':
{
THROW_FMT(OptionInvalidError, "invalid option '%s'", argList[optind - 1]); THROW_FMT(OptionInvalidError, "invalid option '%s'", argList[optind - 1]);
break;
}
// If the option is missing an argument then error // If the option is missing an argument then error
case ':': case ':':
{
THROW_FMT(OptionInvalidError, "option '%s' requires argument", argList[optind - 1]); THROW_FMT(OptionInvalidError, "option '%s' requires argument", argList[optind - 1]);
break;
}
// Parse valid option // Parse valid option
default: default:
@@ -964,4 +985,6 @@ configParse(unsigned int argListSize, const char *argList[])
} }
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -8,6 +8,7 @@ Main
#include "command/archive/push/push.h" #include "command/archive/push/push.h"
#include "command/help/help.h" #include "command/help/help.h"
#include "command/command.h" #include "command/command.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/exit.h" #include "common/exit.h"
#include "config/config.h" #include "config/config.h"
@@ -18,6 +19,15 @@ Main
int int
main(int argListSize, const char *argList[]) main(int argListSize, const char *argList[])
{ {
#ifdef WITH_BACKTRACE
stackTraceInit(argList[0]);
#endif
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(INT, argListSize);
FUNCTION_DEBUG_PARAM(CHARPY, argList);
FUNCTION_DEBUG_END();
volatile bool result = 0; volatile bool result = 0;
volatile bool error = false; volatile bool error = false;
@@ -88,5 +98,5 @@ main(int argListSize, const char *argList[])
} }
TRY_END(); TRY_END();
return exitSafe(result, error, 0); FUNCTION_DEBUG_RESULT(INT, exitSafe(result, error, 0));
} }

View File

@@ -1,6 +1,7 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Perl Configuration Perl Configuration
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
@@ -10,6 +11,8 @@ Build JSON output from options
String * String *
perlOptionJson() perlOptionJson()
{ {
FUNCTION_TEST_VOID();
String *result = strNew("{"); String *result = strNew("{");
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -128,5 +131,5 @@ perlOptionJson()
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_TEST_RESULT(STRING, result);
} }

View File

@@ -8,6 +8,7 @@ Execute Perl for Legacy Functionality
#include <unistd.h> #include <unistd.h>
#include "version.h" #include "version.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
@@ -56,6 +57,8 @@ Build list of parameters to use for perl main
String * String *
perlMain() perlMain()
{ {
FUNCTION_TEST_VOID();
// Add command arguments to pass to main // Add command arguments to pass to main
String *commandParam = strNew(""); String *commandParam = strNew("");
@@ -66,22 +69,23 @@ perlMain()
String *mainCall = strNewFmt( String *mainCall = strNewFmt(
"($result, $message) = " PGBACKREST_MAIN "('%s'%s)", cfgCommandName(cfgCommand()), strPtr(commandParam)); "($result, $message) = " PGBACKREST_MAIN "('%s'%s)", cfgCommandName(cfgCommand()), strPtr(commandParam));
return mainCall; FUNCTION_TEST_RESULT(STRING, mainCall);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Init the dynaloader so other C modules can be loaded Init the dynaloader so other C modules can be loaded
There are no FUNCTION_TEST* calls because this is a callback from Perl and it doesn't seem wise to mix our stack stuff up in it.
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
static void xs_init(pTHX) static void xs_init(pTHX)
{ {
const char *file = __FILE__;
dXSUB_SYS; dXSUB_SYS;
PERL_UNUSED_CONTEXT; PERL_UNUSED_CONTEXT;
/* DynaLoader is a special case */ /* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -90,7 +94,13 @@ Evaluate a perl statement
static void static void
perlEval(const String *statement) perlEval(const String *statement)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, statement);
FUNCTION_TEST_END();
eval_pv(strPtr(statement), TRUE); eval_pv(strPtr(statement), TRUE);
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -99,6 +109,8 @@ Initialize Perl
static void static void
perlInit() perlInit()
{ {
FUNCTION_TEST_VOID();
if (!my_perl) if (!my_perl)
{ {
// Initialize Perl with dummy args and environment // Initialize Perl with dummy args and environment
@@ -123,6 +135,8 @@ perlInit()
// Set config data -- this is done separately to avoid it being included in stack traces // Set config data -- this is done separately to avoid it being included in stack traces
perlEval(strNewFmt(PGBACKREST_MAIN "ConfigSet('%s', '%s')", strPtr(cfgExe()), strPtr(perlOptionJson()))); perlEval(strNewFmt(PGBACKREST_MAIN "ConfigSet('%s', '%s')", strPtr(cfgExe()), strPtr(perlOptionJson())));
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -131,6 +145,8 @@ Execute main function in Perl
int int
perlExec() perlExec()
{ {
FUNCTION_DEBUG_VOID(logLevelDebug);
// Initialize Perl // Initialize Perl
perlInit(); perlInit();
@@ -144,7 +160,7 @@ perlExec()
if (code >= errorTypeCode(&AssertError)) // {uncovered - success tested in integration} if (code >= errorTypeCode(&AssertError)) // {uncovered - success tested in integration}
THROW_CODE(code, strlen(message) == 0 ? PERL_EMBED_ERROR : message); // {+uncovered} THROW_CODE(code, strlen(message) == 0 ? PERL_EMBED_ERROR : message); // {+uncovered}
return code; // {+uncovered} FUNCTION_DEBUG_RESULT(INT, code); // {+uncovered}
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -155,6 +171,12 @@ Don't bother freeing Perl itself since we are about to exit.
void void
perlFree(int result) perlFree(int result)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, result);
FUNCTION_TEST_END();
if (my_perl != NULL) if (my_perl != NULL)
perlEval(strNewFmt(PGBACKREST_MAIN "Cleanup(%d)", result)); perlEval(strNewFmt(PGBACKREST_MAIN "Cleanup(%d)", result));
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -1,6 +1,7 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
PostgreSQL Info PostgreSQL Info
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "postgres/info.h" #include "postgres/info.h"
#include "postgres/type.h" #include "postgres/type.h"
@@ -13,6 +14,11 @@ Map control/catalog version to PostgreSQL version
static uint static uint
pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion) pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT32, controlVersion);
FUNCTION_TEST_PARAM(UINT32, catalogVersion);
FUNCTION_TEST_END();
uint result = 0; uint result = 0;
if (controlVersion == 1002 && catalogVersion == 201707211) if (controlVersion == 1002 && catalogVersion == 201707211)
@@ -44,7 +50,7 @@ pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
controlVersion, catalogVersion); controlVersion, catalogVersion);
} }
return result; FUNCTION_TEST_RESULT(UINT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -53,6 +59,12 @@ Get info from pg_control
PgControlInfo PgControlInfo
pgControlInfo(const String *pgPath) pgControlInfo(const String *pgPath)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, pgPath);
FUNCTION_TEST_ASSERT(pgPath != NULL);
FUNCTION_DEBUG_END();
PgControlInfo result = {0}; PgControlInfo result = {0};
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -73,5 +85,5 @@ pgControlInfo(const String *pgPath)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(PG_CONTROL_INFO, result);
} }

View File

@@ -25,4 +25,12 @@ Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
PgControlInfo pgControlInfo(const String *pgPath); PgControlInfo pgControlInfo(const String *pgPath);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_PG_CONTROL_INFO_TYPE \
PgControlInfo
#define FUNCTION_DEBUG_PG_CONTROL_INFO_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "PgControlInfo", buffer, bufferSize)
#endif #endif

View File

@@ -65,6 +65,7 @@ minimize register spilling. For less sophisticated compilers it might be benefic
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/error.h" #include "common/error.h"
#include "postgres/pageChecksum.h" #include "postgres/pageChecksum.h"
#include "postgres/type.h" #include "postgres/type.h"
@@ -134,10 +135,15 @@ do { \
} while (0) } while (0)
static uint32_t static uint32_t
pageChecksumBlock(const unsigned char *page, uint32_t pageSize) pageChecksumBlock(const unsigned char *page, unsigned int pageSize)
{ {
ASSERT_DEBUG(page != NULL); FUNCTION_TEST_BEGIN();
ASSERT_DEBUG(pageSize == PG_PAGE_SIZE); FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
uint32_t sums[N_SUMS]; uint32_t sums[N_SUMS];
uint32_t (*dataArray)[N_SUMS] = (uint32_t (*)[N_SUMS])page; uint32_t (*dataArray)[N_SUMS] = (uint32_t (*)[N_SUMS])page;
@@ -161,7 +167,7 @@ pageChecksumBlock(const unsigned char *page, uint32_t pageSize)
for (i = 0; i < N_SUMS; i++) for (i = 0; i < N_SUMS; i++)
result ^= sums[i]; result ^= sums[i];
return result; FUNCTION_TEST_RESULT(UINT32, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -173,7 +179,14 @@ The checksum includes the block number (to detect the case where a page is someh
uint16_t uint16_t
pageChecksum(const unsigned char *page, unsigned int blockNo, unsigned int pageSize) pageChecksum(const unsigned char *page, unsigned int blockNo, unsigned int pageSize)
{ {
ASSERT_DEBUG(page != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, blockNo);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
// Save pd_checksum and temporarily set it to zero, so that the checksum calculation isn't affected by the old checksum stored // Save pd_checksum and temporarily set it to zero, so that the checksum calculation isn't affected by the old checksum stored
// on the page. Restore it after, because actually updating the checksum is NOT part of the API of this function. // on the page. Restore it after, because actually updating the checksum is NOT part of the API of this function.
@@ -188,7 +201,7 @@ pageChecksum(const unsigned char *page, unsigned int blockNo, unsigned int pageS
checksum ^= blockNo; checksum ^= blockNo;
// Reduce to a uint16 with an offset of one. That avoids checksums of zero, which seems like a good idea. // Reduce to a uint16 with an offset of one. That avoids checksums of zero, which seems like a good idea.
return (uint16_t)((checksum % 65535) + 1); FUNCTION_TEST_RESULT(UINT16, (uint16_t)(checksum % 65535 + 1));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -198,15 +211,25 @@ bool
pageChecksumTest( pageChecksumTest(
const unsigned char *page, unsigned int blockNo, unsigned int pageSize, uint32_t ignoreWalId, uint32_t ignoreWalOffset) const unsigned char *page, unsigned int blockNo, unsigned int pageSize, uint32_t ignoreWalId, uint32_t ignoreWalOffset)
{ {
ASSERT_DEBUG(page != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UCHARP, page);
FUNCTION_TEST_PARAM(UINT, blockNo);
FUNCTION_TEST_PARAM(UINT, pageSize);
FUNCTION_TEST_PARAM(UINT32, ignoreWalId);
FUNCTION_TEST_PARAM(UINT32, ignoreWalOffset);
return FUNCTION_TEST_ASSERT(page != NULL);
FUNCTION_TEST_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(
BOOL,
// This is a new page so don't test checksum // This is a new page so don't test checksum
((PageHeader)page)->pd_upper == 0 || ((PageHeader)page)->pd_upper == 0 ||
// LSN is after the backup started so checksum is not tested because pages may be torn // LSN is after the backup started so checksum is not tested because pages may be torn
(((PageHeader)page)->pd_lsn.walid >= ignoreWalId && ((PageHeader)page)->pd_lsn.xrecoff >= ignoreWalOffset) || (((PageHeader)page)->pd_lsn.walid >= ignoreWalId && ((PageHeader)page)->pd_lsn.xrecoff >= ignoreWalOffset) ||
// Checksum is valid // Checksum is valid
((PageHeader)page)->pd_checksum == pageChecksum(page, blockNo, pageSize); ((PageHeader)page)->pd_checksum == pageChecksum(page, blockNo, pageSize));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -217,13 +240,21 @@ pageChecksumBufferTest(
const unsigned char *pageBuffer, unsigned int pageBufferSize, unsigned int blockNoBegin, unsigned int pageSize, const unsigned char *pageBuffer, unsigned int pageBufferSize, unsigned int blockNoBegin, unsigned int pageSize,
uint32_t ignoreWalId, uint32_t ignoreWalOffset) uint32_t ignoreWalId, uint32_t ignoreWalOffset)
{ {
ASSERT_DEBUG(pageBuffer != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
ASSERT_DEBUG(pageBufferSize > 0); FUNCTION_DEBUG_PARAM(UCHARP, pageBuffer);
ASSERT_DEBUG(pageSize == PG_PAGE_SIZE); FUNCTION_DEBUG_PARAM(UINT, pageBufferSize);
FUNCTION_DEBUG_PARAM(UINT, blockNoBegin);
FUNCTION_DEBUG_PARAM(UINT, pageSize);
FUNCTION_DEBUG_PARAM(UINT32, ignoreWalId);
FUNCTION_DEBUG_PARAM(UINT32, ignoreWalOffset);
// If the buffer does not represent an even number of pages then error FUNCTION_TEST_ASSERT(pageBuffer != NULL);
if (pageBufferSize % pageSize != 0) FUNCTION_DEBUG_ASSERT(pageBufferSize > 0);
THROW_FMT(AssertError, "buffer size %u, page size %u are not divisible", pageBufferSize, pageSize); FUNCTION_DEBUG_ASSERT(pageSize == PG_PAGE_SIZE);
FUNCTION_DEBUG_ASSERT(pageBufferSize % pageSize == 0);
FUNCTION_DEBUG_END();
bool result = true;
// Loop through all pages in the buffer // Loop through all pages in the buffer
for (unsigned int pageIdx = 0; pageIdx < pageBufferSize / pageSize; pageIdx++) for (unsigned int pageIdx = 0; pageIdx < pageBufferSize / pageSize; pageIdx++)
@@ -232,9 +263,11 @@ pageChecksumBufferTest(
// Return false if the checksums do not match // Return false if the checksums do not match
if (!pageChecksumTest(page, blockNoBegin + pageIdx, pageSize, ignoreWalId, ignoreWalOffset)) if (!pageChecksumTest(page, blockNoBegin + pageIdx, pageSize, ignoreWalId, ignoreWalOffset))
return false; {
result = false;
break;
}
} }
// All checksums match FUNCTION_DEBUG_RESULT(BOOL, result);
return true;
} }

View File

@@ -13,6 +13,7 @@ Storage Driver Posix
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/regExp.h" #include "common/regExp.h"
#include "storage/driver/posix/driver.h" #include "storage/driver/posix/driver.h"
@@ -25,6 +26,12 @@ Does a file/path exist?
bool bool
storageDriverPosixExists(const String *path) storageDriverPosixExists(const String *path)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_ASSERT(path != NULL);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
// Attempt to stat the file to determine if it exists // Attempt to stat the file to determine if it exists
@@ -40,7 +47,7 @@ storageDriverPosixExists(const String *path)
else else
result = !S_ISDIR(statFile.st_mode); result = !S_ISDIR(statFile.st_mode);
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -49,6 +56,13 @@ File/path info
StorageInfo StorageInfo
storageDriverPosixInfo(const String *file, bool ignoreMissing) storageDriverPosixInfo(const String *file, bool ignoreMissing)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, file);
FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing);
FUNCTION_DEBUG_ASSERT(file != NULL);
FUNCTION_DEBUG_END();
StorageInfo result = {0}; StorageInfo result = {0};
// Attempt to stat the file // Attempt to stat the file
@@ -79,7 +93,7 @@ storageDriverPosixInfo(const String *file, bool ignoreMissing)
result.mode = statFile.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); result.mode = statFile.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
} }
return result; FUNCTION_DEBUG_RESULT(STORAGE_INFO, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -88,6 +102,14 @@ Get a list of files from a directory
StringList * StringList *
storageDriverPosixList(const String *path, bool errorOnMissing, const String *expression) storageDriverPosixList(const String *path, bool errorOnMissing, const String *expression)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(BOOL, errorOnMissing);
FUNCTION_DEBUG_PARAM(STRING, expression);
FUNCTION_DEBUG_ASSERT(path != NULL);
FUNCTION_DEBUG_END();
StringList *result = NULL; StringList *result = NULL;
DIR *dir = NULL; DIR *dir = NULL;
@@ -141,7 +163,7 @@ storageDriverPosixList(const String *path, bool errorOnMissing, const String *ex
} }
TRY_END(); TRY_END();
return result; FUNCTION_DEBUG_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -150,6 +172,14 @@ Move a file
bool bool
storageDriverPosixMove(StorageFileReadPosix *source, StorageFileWritePosix *destination) storageDriverPosixMove(StorageFileReadPosix *source, StorageFileWritePosix *destination)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ_POSIX, source);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE_POSIX, destination);
FUNCTION_TEST_ASSERT(source != NULL);
FUNCTION_TEST_ASSERT(destination != NULL);
FUNCTION_DEBUG_END();
bool result = true; bool result = true;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -199,7 +229,7 @@ storageDriverPosixMove(StorageFileReadPosix *source, StorageFileWritePosix *dest
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -208,6 +238,15 @@ Create a path
void void
storageDriverPosixPathCreate(const String *path, bool errorOnExists, bool noParentCreate, mode_t mode) storageDriverPosixPathCreate(const String *path, bool errorOnExists, bool noParentCreate, mode_t mode)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(BOOL, errorOnExists);
FUNCTION_DEBUG_PARAM(BOOL, noParentCreate);
FUNCTION_DEBUG_PARAM(MODE, mode);
FUNCTION_DEBUG_ASSERT(path != NULL);
FUNCTION_DEBUG_END();
// Attempt to create the directory // Attempt to create the directory
if (mkdir(strPtr(path), mode) == -1) if (mkdir(strPtr(path), mode) == -1)
{ {
@@ -221,6 +260,8 @@ storageDriverPosixPathCreate(const String *path, bool errorOnExists, bool noPare
else if (errno != EEXIST || errorOnExists) else if (errno != EEXIST || errorOnExists)
THROW_SYS_ERROR_FMT(PathCreateError, "unable to create path '%s'", strPtr(path)); THROW_SYS_ERROR_FMT(PathCreateError, "unable to create path '%s'", strPtr(path));
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -229,6 +270,14 @@ Remove a path
void void
storageDriverPosixPathRemove(const String *path, bool errorOnMissing, bool recurse) storageDriverPosixPathRemove(const String *path, bool errorOnMissing, bool recurse)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(BOOL, errorOnMissing);
FUNCTION_DEBUG_PARAM(BOOL, recurse);
FUNCTION_DEBUG_ASSERT(path != NULL);
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
// Recurse if requested // Recurse if requested
@@ -267,6 +316,8 @@ storageDriverPosixPathRemove(const String *path, bool errorOnMissing, bool recur
} }
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -275,6 +326,13 @@ Sync a path
void void
storageDriverPosixPathSync(const String *path, bool ignoreMissing) storageDriverPosixPathSync(const String *path, bool ignoreMissing)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing);
FUNCTION_DEBUG_ASSERT(path != NULL);
FUNCTION_DEBUG_END();
// Open directory and handle errors // Open directory and handle errors
int handle = storageFilePosixOpen(path, O_RDONLY, 0, ignoreMissing, &PathOpenError, "sync"); int handle = storageFilePosixOpen(path, O_RDONLY, 0, ignoreMissing, &PathOpenError, "sync");
@@ -287,6 +345,8 @@ storageDriverPosixPathSync(const String *path, bool ignoreMissing)
// Close the directory // Close the directory
storageFilePosixClose(handle, path, &PathCloseError); storageFilePosixClose(handle, path, &PathCloseError);
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -295,10 +355,19 @@ Remove a file
void void
storageDriverPosixRemove(const String *file, bool errorOnMissing) storageDriverPosixRemove(const String *file, bool errorOnMissing)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, file);
FUNCTION_DEBUG_PARAM(BOOL, errorOnMissing);
FUNCTION_DEBUG_ASSERT(file != NULL);
FUNCTION_DEBUG_END();
// Attempt to unlink the file // Attempt to unlink the file
if (unlink(strPtr(file)) == -1) if (unlink(strPtr(file)) == -1)
{ {
if (errorOnMissing || errno != ENOENT) if (errorOnMissing || errno != ENOENT)
THROW_SYS_ERROR_FMT(FileRemoveError, "unable to remove '%s'", strPtr(file)); THROW_SYS_ERROR_FMT(FileRemoveError, "unable to remove '%s'", strPtr(file));
} }
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -10,6 +10,7 @@ Storage File Routines For Posix
#include <unistd.h> #include <unistd.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "storage/driver/posix/driverFile.h" #include "storage/driver/posix/driverFile.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -21,6 +22,19 @@ int
storageFilePosixOpen( storageFilePosixOpen(
const String *name, int flags, mode_t mode, bool ignoreMissing, const ErrorType *errorType, const char *purpose) const String *name, int flags, mode_t mode, bool ignoreMissing, const ErrorType *errorType, const char *purpose)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, name);
FUNCTION_TEST_PARAM(INT, flags);
FUNCTION_TEST_PARAM(MODE, mode);
FUNCTION_TEST_PARAM(BOOL, ignoreMissing);
FUNCTION_TEST_PARAM(ERROR_TYPE, errorType);
FUNCTION_TEST_PARAM(STRINGZ, purpose);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_ASSERT(errorType != NULL);
FUNCTION_TEST_ASSERT(purpose != NULL);
FUNCTION_TEST_END();
int result = -1; int result = -1;
result = open(strPtr(name), flags, mode); result = open(strPtr(name), flags, mode);
@@ -31,7 +45,7 @@ storageFilePosixOpen(
THROWP_SYS_ERROR_FMT(errorType, "unable to open '%s' for %s", strPtr(name), purpose); THROWP_SYS_ERROR_FMT(errorType, "unable to open '%s' for %s", strPtr(name), purpose);
} }
return result; FUNCTION_TEST_RESULT(INT, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -40,6 +54,17 @@ Sync a file/directory handle
void void
storageFilePosixSync(int handle, const String *name, const ErrorType *errorType, bool closeOnError) storageFilePosixSync(int handle, const String *name, const ErrorType *errorType, bool closeOnError)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, handle);
FUNCTION_TEST_PARAM(STRING, name);
FUNCTION_TEST_PARAM(ERROR_TYPE, errorType);
FUNCTION_TEST_PARAM(BOOL, closeOnError);
FUNCTION_TEST_ASSERT(handle != -1);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_ASSERT(errorType != NULL);
FUNCTION_TEST_END();
if (fsync(handle) == -1) if (fsync(handle) == -1)
{ {
int errNo = errno; int errNo = errno;
@@ -50,6 +75,8 @@ storageFilePosixSync(int handle, const String *name, const ErrorType *errorType,
THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, "unable to sync '%s'", strPtr(name)); THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, "unable to sync '%s'", strPtr(name));
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -58,6 +85,18 @@ Close a file/directory handle
void void
storageFilePosixClose(int handle, const String *name, const ErrorType *errorType) storageFilePosixClose(int handle, const String *name, const ErrorType *errorType)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(INT, handle);
FUNCTION_TEST_PARAM(STRING, name);
FUNCTION_TEST_PARAM(ERROR_TYPE, errorType);
FUNCTION_TEST_ASSERT(handle != -1);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_ASSERT(errorType != NULL);
FUNCTION_TEST_END();
if (close(handle) == -1) if (close(handle) == -1)
THROWP_SYS_ERROR_FMT(errorType, "unable to close '%s'", strPtr(name)); THROWP_SYS_ERROR_FMT(errorType, "unable to close '%s'", strPtr(name));
FUNCTION_TEST_RESULT_VOID();
} }

View File

@@ -5,6 +5,7 @@ Storage File Read Driver For Posix
#include <unistd.h> #include <unistd.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "storage/driver/posix/driverFile.h" #include "storage/driver/posix/driverFile.h"
#include "storage/driver/posix/driverRead.h" #include "storage/driver/posix/driverRead.h"
@@ -31,10 +32,16 @@ Create a new file
StorageFileReadPosix * StorageFileReadPosix *
storageFileReadPosixNew(const String *name, bool ignoreMissing, size_t bufferSize) storageFileReadPosixNew(const String *name, bool ignoreMissing, size_t bufferSize)
{ {
StorageFileReadPosix *this = NULL; FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, name);
FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing);
FUNCTION_DEBUG_PARAM(BOOL, bufferSize);
ASSERT_DEBUG(name != NULL); FUNCTION_TEST_ASSERT(name != NULL);
ASSERT_DEBUG(bufferSize > 0); FUNCTION_TEST_ASSERT(bufferSize > 0);
FUNCTION_DEBUG_END();
StorageFileReadPosix *this = NULL;
// Create the file object // Create the file object
MEM_CONTEXT_NEW_BEGIN("StorageFileReadPosix") MEM_CONTEXT_NEW_BEGIN("StorageFileReadPosix")
@@ -49,7 +56,7 @@ storageFileReadPosixNew(const String *name, bool ignoreMissing, size_t bufferSiz
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(STORAGE_FILE_READ_POSIX, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -58,10 +65,14 @@ Open the file
bool bool
storageFileReadPosixOpen(StorageFileReadPosix *this) storageFileReadPosixOpen(StorageFileReadPosix *this)
{ {
bool result = false; FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ_POSIX, this);
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_ASSERT(this != NULL);
ASSERT_DEBUG(this->handle == -1); FUNCTION_TEST_ASSERT(this->handle == -1);
FUNCTION_DEBUG_END();
bool result = false;
// Open the file and handle errors // Open the file and handle errors
this->handle = storageFilePosixOpen(this->name, O_RDONLY, 0, this->ignoreMissing, &FileOpenError, "read"); this->handle = storageFilePosixOpen(this->name, O_RDONLY, 0, this->ignoreMissing, &FileOpenError, "read");
@@ -73,7 +84,7 @@ storageFileReadPosixOpen(StorageFileReadPosix *this)
result = true; result = true;
} }
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -82,6 +93,13 @@ Read from a file
Buffer * Buffer *
storageFileReadPosix(StorageFileReadPosix *this) storageFileReadPosix(StorageFileReadPosix *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ_POSIX, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(this->handle != -1);
FUNCTION_DEBUG_END();
Buffer *result = NULL; Buffer *result = NULL;
ASSERT_DEBUG(this != NULL); ASSERT_DEBUG(this != NULL);
@@ -112,7 +130,7 @@ storageFileReadPosix(StorageFileReadPosix *this)
} }
} }
return result; FUNCTION_DEBUG_RESULT(BUFFER, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -121,7 +139,11 @@ Close the file
void void
storageFileReadPosixClose(StorageFileReadPosix *this) storageFileReadPosixClose(StorageFileReadPosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ_POSIX, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Close if the file has not already been closed // Close if the file has not already been closed
if (this->handle != -1) if (this->handle != -1)
@@ -131,6 +153,8 @@ storageFileReadPosixClose(StorageFileReadPosix *this)
this->handle = -1; this->handle = -1;
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -139,9 +163,13 @@ Should a missing file be ignored?
bool bool
storageFileReadPosixIgnoreMissing(StorageFileReadPosix *this) storageFileReadPosixIgnoreMissing(StorageFileReadPosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_POSIX, this);
return this->ignoreMissing; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, this->ignoreMissing);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -150,9 +178,13 @@ File name
const String * const String *
storageFileReadPosixName(StorageFileReadPosix *this) storageFileReadPosixName(StorageFileReadPosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_POSIX, this);
return this->name; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, this->name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -161,9 +193,13 @@ File size
size_t size_t
storageFileReadPosixSize(StorageFileReadPosix *this) storageFileReadPosixSize(StorageFileReadPosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_POSIX, this);
return this->size; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -172,9 +208,15 @@ Free the file
void void
storageFileReadPosixFree(StorageFileReadPosix *this) storageFileReadPosixFree(StorageFileReadPosix *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ_POSIX, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
{ {
storageFileReadPosixClose(this); storageFileReadPosixClose(this);
memContextFree(this->memContext); memContextFree(this->memContext);
} }
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -36,4 +36,12 @@ Destructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void storageFileReadPosixFree(StorageFileReadPosix *this); void storageFileReadPosixFree(StorageFileReadPosix *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_STORAGE_FILE_READ_POSIX_TYPE \
StorageFileReadPosix *
#define FUNCTION_DEBUG_STORAGE_FILE_READ_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileReadPosix", buffer, bufferSize)
#endif #endif

View File

@@ -6,6 +6,7 @@ Storage File Write Driver For Posix
#include <unistd.h> #include <unistd.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "storage/driver/posix/driverFile.h" #include "storage/driver/posix/driverFile.h"
#include "storage/driver/posix/driverWrite.h" #include "storage/driver/posix/driverWrite.h"
@@ -48,6 +49,18 @@ StorageFileWritePosix *
storageFileWritePosixNew( storageFileWritePosixNew(
const String *name, mode_t modeFile, mode_t modePath, bool noCreatePath, bool noSyncFile, bool noSyncPath, bool noAtomic) const String *name, mode_t modeFile, mode_t modePath, bool noCreatePath, bool noSyncFile, bool noSyncPath, bool noAtomic)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, name);
FUNCTION_DEBUG_PARAM(MODE, modeFile);
FUNCTION_DEBUG_PARAM(MODE, modePath);
FUNCTION_DEBUG_PARAM(BOOL, noCreatePath);
FUNCTION_DEBUG_PARAM(BOOL, noSyncFile);
FUNCTION_DEBUG_PARAM(BOOL, noSyncPath);
FUNCTION_DEBUG_PARAM(BOOL, noAtomic);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_DEBUG_END();
StorageFileWritePosix *this = NULL; StorageFileWritePosix *this = NULL;
ASSERT_DEBUG(name != NULL); ASSERT_DEBUG(name != NULL);
@@ -71,7 +84,7 @@ storageFileWritePosixNew(
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(STORAGE_FILE_WRITE_POSIX, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -80,8 +93,12 @@ Open the file
void void
storageFileWritePosixOpen(StorageFileWritePosix *this) storageFileWritePosixOpen(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
ASSERT_DEBUG(this->handle == -1); FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE_POSIX, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(this->handle == -1);
FUNCTION_DEBUG_END();
// Open the file and handle errors // Open the file and handle errors
this->handle = storageFilePosixOpen( this->handle = storageFilePosixOpen(
@@ -100,6 +117,8 @@ storageFileWritePosixOpen(StorageFileWritePosix *this)
// On success set free callback to ensure file handle is freed // On success set free callback to ensure file handle is freed
else else
memContextCallback(this->memContext, (MemContextCallback)storageFileWritePosixFree, this); memContextCallback(this->memContext, (MemContextCallback)storageFileWritePosixFree, this);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -108,13 +127,20 @@ Write to a file
void void
storageFileWritePosix(StorageFileWritePosix *this, const Buffer *buffer) storageFileWritePosix(StorageFileWritePosix *this, const Buffer *buffer)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
ASSERT_DEBUG(buffer != NULL); FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE_POSIX, this);
ASSERT_DEBUG(this->handle != -1); FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_TEST_ASSERT(this->handle != -1);
FUNCTION_DEBUG_END();
// Write the data // Write the data
if (write(this->handle, bufPtr(buffer), bufSize(buffer)) != (ssize_t)bufSize(buffer)) if (write(this->handle, bufPtr(buffer), bufSize(buffer)) != (ssize_t)bufSize(buffer))
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->name)); THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->name));
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -123,7 +149,11 @@ Close the file
void void
storageFileWritePosixClose(StorageFileWritePosix *this) storageFileWritePosixClose(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE_POSIX, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Close if the file has not already been closed // Close if the file has not already been closed
if (this->handle != -1) if (this->handle != -1)
@@ -149,6 +179,8 @@ storageFileWritePosixClose(StorageFileWritePosix *this)
// This marks the file as closed // This marks the file as closed
this->handle = -1; this->handle = -1;
} }
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -159,9 +191,13 @@ For the posix driver this means writing to a temp file first and then renaming o
bool bool
storageFileWritePosixAtomic(StorageFileWritePosix *this) storageFileWritePosixAtomic(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return !this->noAtomic; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, !this->noAtomic);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -170,9 +206,13 @@ Will the path be created for the file if it does not exist?
bool bool
storageFileWritePosixCreatePath(StorageFileWritePosix *this) storageFileWritePosixCreatePath(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return !this->noCreatePath; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, !this->noCreatePath);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -181,9 +221,13 @@ Mode for the file to be created
mode_t mode_t
storageFileWritePosixModeFile(StorageFileWritePosix *this) storageFileWritePosixModeFile(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return this->modeFile; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(MODE, this->modeFile);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -192,9 +236,13 @@ Mode for any paths that are created while writing the file
mode_t mode_t
storageFileWritePosixModePath(StorageFileWritePosix *this) storageFileWritePosixModePath(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return this->modePath; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(MODE, this->modePath);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -203,9 +251,13 @@ File name
const String * const String *
storageFileWritePosixName(StorageFileWritePosix *this) storageFileWritePosixName(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return this->name; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, this->name);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -214,9 +266,13 @@ File path
const String * const String *
storageFileWritePosixPath(StorageFileWritePosix *this) storageFileWritePosixPath(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return this->path; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, this->path);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -225,9 +281,13 @@ Will the file be synced after it is closed?
bool bool
storageFileWritePosixSyncFile(StorageFileWritePosix *this) storageFileWritePosixSyncFile(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return !this->noSyncFile; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, !this->noSyncFile);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -236,9 +296,13 @@ Will the directory be synced to disk after the write is completed?
bool bool
storageFileWritePosixSyncPath(StorageFileWritePosix *this) storageFileWritePosixSyncPath(StorageFileWritePosix *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE_POSIX, this);
return !this->noSyncPath; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, !this->noSyncPath);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -247,9 +311,15 @@ Free the file
void void
storageFileWritePosixFree(StorageFileWritePosix *this) storageFileWritePosixFree(StorageFileWritePosix *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE_POSIX, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
{ {
storageFileWritePosixClose(this); storageFileWritePosixClose(this);
memContextFree(this->memContext); memContextFree(this->memContext);
} }
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -44,4 +44,12 @@ Destructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void storageFileWritePosixFree(StorageFileWritePosix *this); void storageFileWritePosixFree(StorageFileWritePosix *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_STORAGE_FILE_WRITE_POSIX_TYPE \
StorageFileWritePosix *
#define FUNCTION_DEBUG_STORAGE_FILE_WRITE_POSIX_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileWritePosix", buffer, bufferSize)
#endif #endif

View File

@@ -2,6 +2,7 @@
Storage File Read Storage File Read
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "storage/fileRead.h" #include "storage/fileRead.h"
@@ -20,9 +21,16 @@ Create a new storage file
StorageFileRead * StorageFileRead *
storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize) storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize)
{ {
StorageFileRead *this = NULL; FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, name);
FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing);
FUNCTION_DEBUG_PARAM(BOOL, bufferSize);
ASSERT_DEBUG(name != NULL); FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_ASSERT(bufferSize > 0);
FUNCTION_DEBUG_END();
StorageFileRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageFileRead") MEM_CONTEXT_NEW_BEGIN("StorageFileRead")
{ {
@@ -34,7 +42,7 @@ storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(STORAGE_FILE_READ, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -43,9 +51,13 @@ Open the file
bool bool
storageFileReadOpen(StorageFileRead *this) storageFileReadOpen(StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
return storageFileReadPosixOpen(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BOOL, storageFileReadPosixOpen(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -54,9 +66,13 @@ Read data from the file
Buffer * Buffer *
storageFileRead(StorageFileRead *this) storageFileRead(StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
return storageFileReadPosix(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BUFFER, storageFileReadPosix(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -65,10 +81,17 @@ Move the file object to a new context
StorageFileRead * StorageFileRead *
storageFileReadMove(StorageFileRead *this, MemContext *parentNew) storageFileReadMove(StorageFileRead *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextMove(this->memContext, parentNew); memContextMove(this->memContext, parentNew);
return this; FUNCTION_TEST_RESULT(STORAGE_FILE_READ, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -77,9 +100,15 @@ Close the file
void void
storageFileReadClose(StorageFileRead *this) storageFileReadClose(StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
storageFileReadPosixClose(this->fileDriver); storageFileReadPosixClose(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -88,9 +117,13 @@ Get file driver
StorageFileReadPosix * StorageFileReadPosix *
storageFileReadFileDriver(const StorageFileRead *this) storageFileReadFileDriver(const StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
return this->fileDriver; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STORAGE_FILE_READ_POSIX, this->fileDriver);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -99,9 +132,13 @@ Should a missing file be ignored?
bool bool
storageFileReadIgnoreMissing(const StorageFileRead *this) storageFileReadIgnoreMissing(const StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
return storageFileReadPosixIgnoreMissing(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileReadPosixIgnoreMissing(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -110,9 +147,13 @@ Get file name
const String * const String *
storageFileReadName(const StorageFileRead *this) storageFileReadName(const StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
return storageFileReadPosixName(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, storageFileReadPosixName(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -121,9 +162,13 @@ Get file size
size_t size_t
storageFileReadSize(const StorageFileRead *this) storageFileReadSize(const StorageFileRead *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
return storageFileReadPosixSize(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, storageFileReadPosixSize(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -132,6 +177,12 @@ Free the file
void void
storageFileReadFree(StorageFileRead *this) storageFileReadFree(StorageFileRead *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -40,4 +40,12 @@ Destructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void storageFileReadFree(StorageFileRead *this); void storageFileReadFree(StorageFileRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_STORAGE_FILE_READ_TYPE \
StorageFileRead *
#define FUNCTION_DEBUG_STORAGE_FILE_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileRead", buffer, bufferSize)
#endif #endif

View File

@@ -2,6 +2,7 @@
Storage File Write Storage File Write
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "storage/fileWrite.h" #include "storage/fileWrite.h"
@@ -24,6 +25,18 @@ StorageFileWrite *
storageFileWriteNew( storageFileWriteNew(
const String *name, mode_t modeFile, mode_t modePath, bool noCreatePath, bool noSyncFile, bool noSyncPath, bool noAtomic) const String *name, mode_t modeFile, mode_t modePath, bool noCreatePath, bool noSyncFile, bool noSyncPath, bool noAtomic)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, name);
FUNCTION_DEBUG_PARAM(MODE, modeFile);
FUNCTION_DEBUG_PARAM(MODE, modePath);
FUNCTION_DEBUG_PARAM(BOOL, noCreatePath);
FUNCTION_DEBUG_PARAM(BOOL, noSyncFile);
FUNCTION_DEBUG_PARAM(BOOL, noSyncPath);
FUNCTION_DEBUG_PARAM(BOOL, noAtomic);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_DEBUG_END();
StorageFileWrite *this = NULL; StorageFileWrite *this = NULL;
ASSERT_DEBUG(name != NULL); ASSERT_DEBUG(name != NULL);
@@ -39,7 +52,7 @@ storageFileWriteNew(
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(STORAGE_FILE_WRITE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -48,10 +61,16 @@ Open the file
void void
storageFileWriteOpen(StorageFileWrite *this) storageFileWriteOpen(StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Open the file // Open the file
storageFileWritePosixOpen(this->fileDriver); storageFileWritePosixOpen(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -60,11 +79,18 @@ Write to a file
void void
storageFileWrite(StorageFileWrite *this, const Buffer *buffer) storageFileWrite(StorageFileWrite *this, const Buffer *buffer)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Only write if there is data to write // Only write if there is data to write
if (buffer != NULL && bufSize(buffer) > 0) if (buffer != NULL && bufSize(buffer) > 0)
storageFileWritePosix(this->fileDriver, buffer); storageFileWritePosix(this->fileDriver, buffer);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -73,10 +99,17 @@ Move the file object to a new context
StorageFileWrite * StorageFileWrite *
storageFileWriteMove(StorageFileWrite *this, MemContext *parentNew) storageFileWriteMove(StorageFileWrite *this, MemContext *parentNew)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL) if (this != NULL)
memContextMove(this->memContext, parentNew); memContextMove(this->memContext, parentNew);
return this; FUNCTION_TEST_RESULT(STORAGE_FILE_WRITE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -85,9 +118,15 @@ Close the file
void void
storageFileWriteClose(StorageFileWrite *this) storageFileWriteClose(StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
storageFileWritePosixClose(this->fileDriver); storageFileWritePosixClose(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -98,9 +137,13 @@ Atomic writes means the file will be complete or be missing. Filesystems have d
bool bool
storageFileWriteAtomic(const StorageFileWrite *this) storageFileWriteAtomic(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixAtomic(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileWritePosixAtomic(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -109,9 +152,13 @@ Will the path be created if required?
bool bool
storageFileWriteCreatePath(const StorageFileWrite *this) storageFileWriteCreatePath(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixCreatePath(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileWritePosixCreatePath(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -120,9 +167,13 @@ Get file driver
StorageFileWritePosix * StorageFileWritePosix *
storageFileWriteFileDriver(const StorageFileWrite *this) storageFileWriteFileDriver(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return this->fileDriver; FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(STORAGE_FILE_WRITE_POSIX, this->fileDriver);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -131,9 +182,13 @@ Get file mode
mode_t mode_t
storageFileWriteModeFile(const StorageFileWrite *this) storageFileWriteModeFile(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixModeFile(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(MODE, storageFileWritePosixModeFile(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -142,9 +197,13 @@ Get path mode
mode_t mode_t
storageFileWriteModePath(const StorageFileWrite *this) storageFileWriteModePath(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixModePath(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(MODE, storageFileWritePosixModePath(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -153,9 +212,13 @@ Get file name
const String * const String *
storageFileWriteName(const StorageFileWrite *this) storageFileWriteName(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixName(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, storageFileWritePosixName(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -164,9 +227,13 @@ Get file path
const String * const String *
storageFileWritePath(const StorageFileWrite *this) storageFileWritePath(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixPath(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(CONST_STRING, storageFileWritePosixPath(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -175,9 +242,13 @@ Will the file be synced after it is closed?
bool bool
storageFileWriteSyncFile(const StorageFileWrite *this) storageFileWriteSyncFile(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixSyncFile(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileWritePosixSyncFile(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -186,9 +257,13 @@ Will the path be synced after the file is closed?
bool bool
storageFileWriteSyncPath(const StorageFileWrite *this) storageFileWriteSyncPath(const StorageFileWrite *this)
{ {
ASSERT_DEBUG(this != NULL); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
return storageFileWritePosixSyncPath(this->fileDriver); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileWritePosixSyncPath(this->fileDriver));
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -197,6 +272,12 @@ Free the file
void void
storageFileWriteFree(const StorageFileWrite *this) storageFileWriteFree(const StorageFileWrite *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -54,4 +54,12 @@ Destructor
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void storageFileWriteFree(const StorageFileWrite *this); void storageFileWriteFree(const StorageFileWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_STORAGE_FILE_WRITE_TYPE \
StorageFileWrite *
#define FUNCTION_DEBUG_STORAGE_FILE_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "StorageFileWrite", buffer, bufferSize)
#endif #endif

View File

@@ -3,6 +3,7 @@ Storage Helper
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <string.h> #include <string.h>
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "config/config.h" #include "config/config.h"
#include "storage/helper.h" #include "storage/helper.h"
@@ -30,6 +31,8 @@ Create the storage helper memory context
static void static void
storageHelperInit() storageHelperInit()
{ {
FUNCTION_TEST_VOID();
if (memContextStorageHelper == NULL) if (memContextStorageHelper == NULL)
{ {
MEM_CONTEXT_BEGIN(memContextTop()) MEM_CONTEXT_BEGIN(memContextTop())
@@ -38,6 +41,8 @@ storageHelperInit()
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
FUNCTION_TEST_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -46,10 +51,12 @@ Get a local storage object
const Storage * const Storage *
storageLocal() storageLocal()
{ {
storageHelperInit(); FUNCTION_TEST_VOID();
if (storageLocalData == NULL) if (storageLocalData == NULL)
{ {
storageHelperInit();
MEM_CONTEXT_BEGIN(memContextStorageHelper) MEM_CONTEXT_BEGIN(memContextStorageHelper)
{ {
storageLocalData = storageNewNP(strNew("/")); storageLocalData = storageNewNP(strNew("/"));
@@ -57,7 +64,7 @@ storageLocal()
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
return storageLocalData; FUNCTION_TEST_RESULT(STORAGE, storageLocalData);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -68,10 +75,12 @@ This should be used very sparingly. If writes are not needed then always use st
const Storage * const Storage *
storageLocalWrite() storageLocalWrite()
{ {
storageHelperInit(); FUNCTION_TEST_VOID();
if (storageLocalWriteData == NULL) if (storageLocalWriteData == NULL)
{ {
storageHelperInit();
MEM_CONTEXT_BEGIN(memContextStorageHelper) MEM_CONTEXT_BEGIN(memContextStorageHelper)
{ {
storageLocalWriteData = storageNewP(strNew("/"), .write = true); storageLocalWriteData = storageNewP(strNew("/"), .write = true);
@@ -79,7 +88,7 @@ storageLocalWrite()
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
return storageLocalWriteData; FUNCTION_TEST_RESULT(STORAGE, storageLocalWriteData);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -88,6 +97,13 @@ Get a spool storage object
String * String *
storageSpoolPathExpression(const String *expression, const String *path) storageSpoolPathExpression(const String *expression, const String *path)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, expression);
FUNCTION_TEST_PARAM(STRING, path);
FUNCTION_TEST_ASSERT(expression != NULL);
FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
if (strcmp(strPtr(expression), STORAGE_SPOOL_ARCHIVE_IN) == 0) if (strcmp(strPtr(expression), STORAGE_SPOOL_ARCHIVE_IN) == 0)
@@ -107,7 +123,7 @@ storageSpoolPathExpression(const String *expression, const String *path)
else else
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression)); THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
return result; FUNCTION_TEST_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -116,10 +132,12 @@ Get a spool storage object
const Storage * const Storage *
storageSpool() storageSpool()
{ {
storageHelperInit(); FUNCTION_TEST_VOID();
if (storageSpoolData == NULL) if (storageSpoolData == NULL)
{ {
storageHelperInit();
MEM_CONTEXT_BEGIN(memContextStorageHelper) MEM_CONTEXT_BEGIN(memContextStorageHelper)
{ {
storageSpoolStanza = strDup(cfgOptionStr(cfgOptStanza)); storageSpoolStanza = strDup(cfgOptionStr(cfgOptStanza));
@@ -130,5 +148,5 @@ storageSpool()
MEM_CONTEXT_END(); MEM_CONTEXT_END();
} }
return storageSpoolData; FUNCTION_TEST_RESULT(STORAGE, storageSpoolData);
} }

View File

@@ -27,4 +27,12 @@ typedef struct StorageInfo
mode_t mode; // Mode of path/file/link mode_t mode; // Mode of path/file/link
} StorageInfo; } StorageInfo;
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_STORAGE_INFO_TYPE \
StorageInfo
#define FUNCTION_DEBUG_STORAGE_INFO_FORMAT(value, buffer, bufferSize) \
objToLog(&value, "StorageInfo", buffer, bufferSize)
#endif #endif

View File

@@ -1,9 +1,11 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Storage Manager Storage Manager
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <stdio.h>
#include <string.h> #include <string.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/debug.h"
#include "common/memContext.h" #include "common/memContext.h"
#include "common/wait.h" #include "common/wait.h"
#include "storage/driver/posix/driver.h" #include "storage/driver/posix/driver.h"
@@ -23,24 +25,24 @@ struct Storage
StoragePathExpressionCallback pathExpressionFunction; StoragePathExpressionCallback pathExpressionFunction;
}; };
/***********************************************************************************************************************************
Debug Asserts
***********************************************************************************************************************************/
// Check that commands that write are not allowed unless the storage is writable
#define ASSERT_STORAGE_ALLOWS_WRITE() \
ASSERT(this->write == true)
/*********************************************************************************************************************************** /***********************************************************************************************************************************
New storage object New storage object
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
Storage * Storage *
storageNew(const String *path, StorageNewParam param) storageNew(const String *path, StorageNewParam param)
{ {
Storage *this = NULL; FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(MODE, param.modeFile);
FUNCTION_DEBUG_PARAM(MODE, param.modePath);
FUNCTION_DEBUG_PARAM(SIZE, param.bufferSize);
FUNCTION_DEBUG_PARAM(BOOL, param.write);
FUNCTION_DEBUG_PARAM(FUNCTIONP, param.pathExpressionFunction);
// Path is required FUNCTION_DEBUG_ASSERT(path != NULL);
if (path == NULL) FUNCTION_DEBUG_END();
THROW(AssertError, "storage base path cannot be null");
Storage *this = NULL;
// Create the storage // Create the storage
MEM_CONTEXT_NEW_BEGIN("Storage") MEM_CONTEXT_NEW_BEGIN("Storage")
@@ -56,7 +58,7 @@ storageNew(const String *path, StorageNewParam param)
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return this; FUNCTION_DEBUG_RESULT(STORAGE, this);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -65,6 +67,14 @@ Copy a file
bool bool
storageCopy(StorageFileRead *source, StorageFileWrite *destination) storageCopy(StorageFileRead *source, StorageFileWrite *destination)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, source);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, destination);
FUNCTION_TEST_ASSERT(source != NULL);
FUNCTION_TEST_ASSERT(destination != NULL);
FUNCTION_DEBUG_END();
bool result = false; bool result = false;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -95,7 +105,7 @@ storageCopy(StorageFileRead *source, StorageFileWrite *destination)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -104,10 +114,16 @@ Does a file/path exist?
bool bool
storageExists(const Storage *this, const String *pathExp, StorageExistsParam param) storageExists(const Storage *this, const String *pathExp, StorageExistsParam param)
{ {
bool result = false; FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, pathExp);
FUNCTION_DEBUG_PARAM(DOUBLE, param.timeout);
// Timeout can't be negative FUNCTION_TEST_ASSERT(this != NULL);
ASSERT_DEBUG(param.timeout >= 0); FUNCTION_DEBUG_ASSERT(param.timeout >= 0);
FUNCTION_DEBUG_END();
bool result = false;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -127,7 +143,7 @@ storageExists(const Storage *this, const String *pathExp, StorageExistsParam par
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -136,9 +152,13 @@ Read from storage into a buffer
Buffer * Buffer *
storageGet(StorageFileRead *file) storageGet(StorageFileRead *file)
{ {
Buffer *result = NULL; FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, file);
ASSERT_DEBUG(file != NULL); FUNCTION_TEST_ASSERT(file != NULL);
FUNCTION_DEBUG_END();
Buffer *result = NULL;
// If the file exists // If the file exists
if (storageFileReadOpen(file)) if (storageFileReadOpen(file))
@@ -166,7 +186,7 @@ storageGet(StorageFileRead *file)
storageFileReadClose(file); storageFileReadClose(file);
} }
return result; FUNCTION_DEBUG_RESULT(BUFFER, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -175,6 +195,14 @@ File/path info
StorageInfo StorageInfo
storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param) storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
StorageInfo result = {0}; StorageInfo result = {0};
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -187,7 +215,7 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STORAGE_INFO, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -196,6 +224,15 @@ Get a list of files from a directory
StringList * StringList *
storageList(const Storage *this, const String *pathExp, StorageListParam param) storageList(const Storage *this, const String *pathExp, StorageListParam param)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, pathExp);
FUNCTION_DEBUG_PARAM(BOOL, param.errorOnMissing);
FUNCTION_DEBUG_PARAM(STRING, param.expression);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
StringList *result = NULL; StringList *result = NULL;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
@@ -208,7 +245,7 @@ storageList(const Storage *this, const String *pathExp, StorageListParam param)
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STRING_LIST, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -217,7 +254,14 @@ Move a file
void void
storageMove(StorageFileRead *source, StorageFileWrite *destination) storageMove(StorageFileRead *source, StorageFileWrite *destination)
{ {
ASSERT_DEBUG(!storageFileReadIgnoreMissing(source)); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, source);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, destination);
FUNCTION_TEST_ASSERT(source != NULL);
FUNCTION_TEST_ASSERT(destination != NULL);
FUNCTION_DEBUG_ASSERT(!storageFileReadIgnoreMissing(source));
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -237,6 +281,8 @@ storageMove(StorageFileRead *source, StorageFileWrite *destination)
} }
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -245,6 +291,14 @@ Open a file for reading
StorageFileRead * StorageFileRead *
storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam param) storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam param)
{ {
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
StorageFileRead *result = NULL; StorageFileRead *result = NULL;
MEM_CONTEXT_NEW_BEGIN("StorageFileRead") MEM_CONTEXT_NEW_BEGIN("StorageFileRead")
@@ -256,7 +310,7 @@ storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam p
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
return result; FUNCTION_DEBUG_RESULT(STORAGE_FILE_READ, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -265,9 +319,21 @@ Open a file for writing
StorageFileWrite * StorageFileWrite *
storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam param) storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam param)
{ {
StorageFileWrite *result = NULL; FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(MODE, param.modeFile);
FUNCTION_DEBUG_PARAM(MODE, param.modePath);
FUNCTION_DEBUG_PARAM(BOOL, param.noCreatePath);
FUNCTION_DEBUG_PARAM(BOOL, param.noSyncFile);
FUNCTION_DEBUG_PARAM(BOOL, param.noSyncPath);
FUNCTION_DEBUG_PARAM(BOOL, param.noAtomic);
ASSERT_STORAGE_ALLOWS_WRITE(); FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(this->write);
FUNCTION_DEBUG_END();
StorageFileWrite *result = NULL;
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -283,7 +349,7 @@ storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
return result; FUNCTION_DEBUG_RESULT(STORAGE_FILE_WRITE, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -292,6 +358,13 @@ Get the absolute path in the storage
String * String *
storagePath(const Storage *this, const String *pathExp) storagePath(const Storage *this, const String *pathExp)
{ {
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE, this);
FUNCTION_TEST_PARAM(STRING, pathExp);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
// If there there is no path expression then return the base storage path // If there there is no path expression then return the base storage path
@@ -378,7 +451,7 @@ storagePath(const Storage *this, const String *pathExp)
} }
} }
return result; FUNCTION_TEST_RESULT(STRING, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -387,11 +460,21 @@ Create a path
void void
storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateParam param) storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateParam param)
{ {
ASSERT_STORAGE_ALLOWS_WRITE(); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, pathExp);
FUNCTION_DEBUG_PARAM(BOOL, param.errorOnExists);
FUNCTION_DEBUG_PARAM(BOOL, param.noParentCreate);
FUNCTION_DEBUG_PARAM(MODE, param.mode);
// It doesn't make sense to combine these parameters because if we are creating missing parent paths why error when they exist? FUNCTION_TEST_ASSERT(this != NULL);
// If this somehow wasn't caught in testing, the worst case is that the path would not be created and an error would be thrown. FUNCTION_DEBUG_ASSERT(this->write);
ASSERT_DEBUG(!(param.noParentCreate && param.errorOnExists));
// It doesn't make sense to combine these parameters because if we are creating missing parent paths why error when they
// exist? If this somehow wasn't caught in testing, the worst case is that the path would not be created and an error would
// be thrown.
FUNCTION_TEST_ASSERT(!(param.noParentCreate && param.errorOnExists));
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -403,6 +486,8 @@ storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateP
path, param.errorOnExists, param.noParentCreate, param.mode != 0 ? param.mode : this->modePath); path, param.errorOnExists, param.noParentCreate, param.mode != 0 ? param.mode : this->modePath);
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -411,7 +496,15 @@ Remove a path
void void
storagePathRemove(const Storage *this, const String *pathExp, StoragePathRemoveParam param) storagePathRemove(const Storage *this, const String *pathExp, StoragePathRemoveParam param)
{ {
ASSERT_STORAGE_ALLOWS_WRITE(); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, pathExp);
FUNCTION_DEBUG_PARAM(BOOL, param.errorOnMissing);
FUNCTION_DEBUG_PARAM(BOOL, param.recurse);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(this->write);
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -422,6 +515,8 @@ storagePathRemove(const Storage *this, const String *pathExp, StoragePathRemoveP
storageDriverPosixPathRemove(path, param.errorOnMissing, param.recurse); storageDriverPosixPathRemove(path, param.errorOnMissing, param.recurse);
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -429,7 +524,14 @@ Sync a path
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
void storagePathSync(const Storage *this, const String *pathExp, StoragePathSyncParam param) void storagePathSync(const Storage *this, const String *pathExp, StoragePathSyncParam param)
{ {
ASSERT_STORAGE_ALLOWS_WRITE(); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, pathExp);
FUNCTION_DEBUG_PARAM(BOOL, param.ignoreMissing);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(this->write);
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -440,6 +542,8 @@ void storagePathSync(const Storage *this, const String *pathExp, StoragePathSync
storageDriverPosixPathSync(path, param.ignoreMissing); storageDriverPosixPathSync(path, param.ignoreMissing);
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -448,9 +552,18 @@ Write a buffer to storage
void void
storagePut(StorageFileWrite *file, const Buffer *buffer) storagePut(StorageFileWrite *file, const Buffer *buffer)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, file);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_ASSERT(file != NULL);
FUNCTION_DEBUG_END();
storageFileWriteOpen(file); storageFileWriteOpen(file);
storageFileWrite(file, buffer); storageFileWrite(file, buffer);
storageFileWriteClose(file); storageFileWriteClose(file);
FUNCTION_DEBUG_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -459,7 +572,14 @@ Remove a file
void void
storageRemove(const Storage *this, const String *fileExp, StorageRemoveParam param) storageRemove(const Storage *this, const String *fileExp, StorageRemoveParam param)
{ {
ASSERT_STORAGE_ALLOWS_WRITE(); FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_PARAM(STRING, fileExp);
FUNCTION_DEBUG_PARAM(BOOL, param.errorOnMissing);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(this->write);
FUNCTION_DEBUG_END();
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
@@ -470,6 +590,32 @@ storageRemove(const Storage *this, const String *fileExp, StorageRemoveParam par
storageDriverPosixRemove(file, param.errorOnMissing); storageDriverPosixRemove(file, param.errorOnMissing);
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Convert to a zero-terminated string for logging
***********************************************************************************************************************************/
size_t
storageToLog(const Storage *this, char *buffer, size_t bufferSize)
{
size_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
String *string = NULL;
if (this == NULL)
string = strNew("null");
else
string = strNewFmt("{path: %s, write: %s}", strPtr(strQuoteZ(this->path, "\"")), this->write ? "true" : "false");
result = (size_t)snprintf(buffer, bufferSize, "%s", strPtr(string));
}
MEM_CONTEXT_TEMP_END();
return result;
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -478,6 +624,12 @@ Free storage
void void
storageFree(const Storage *this) storageFree(const Storage *this)
{ {
FUNCTION_DEBUG_BEGIN(logLevelDebug);
FUNCTION_DEBUG_PARAM(STORAGE, this);
FUNCTION_DEBUG_END();
if (this != NULL) if (this != NULL)
memContextFree(this->memContext); memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
} }

View File

@@ -247,4 +247,14 @@ storageFree
void storageFree(const Storage *this); void storageFree(const Storage *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
size_t storageToLog(const Storage *this, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_STORAGE_TYPE \
Storage *
#define FUNCTION_DEBUG_STORAGE_FORMAT(value, buffer, bufferSize) \
(size_t)storageToLog(value, buffer, bufferSize)
#endif #endif

5
test/Vagrantfile vendored
View File

@@ -43,9 +43,8 @@ Vagrant.configure(2) do |config|
# Set time sync settings so builds don't fail with clock drift errors # Set time sync settings so builds don't fail with clock drift errors
#--------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------
echo 'Time Sync Settings' && date echo 'Time Sync Settings' && date
/etc/init.d/virtualbox-guest-utils stop sudo /etc/init.d/virtualbox-guest-utils stop
/usr/sbin/VBoxService --timesync-set-on-restore 1 --timesync-interval 5000 --timesync-set-threshold 1 sudo /usr/sbin/VBoxService --timesync-set-on-restore 1 --timesync-interval 5000 --timesync-set-threshold 1
/etc/init.d/virtualbox-guest-utils start
#--------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------
echo 'Install Perl Modules' && date echo 'Install Perl Modules' && date

View File

@@ -33,18 +33,10 @@ unit:
- name: common - name: common
test: test:
# ----------------------------------------------------------------------------------------------------------------------------
- name: time
total: 2
define: -DNO_ERROR -DNO_LOG
coverage:
common/time: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: error - name: error
total: 8 total: 8
define: -DNO_ERROR -DNO_LOG define: -DNO_ERROR -DNO_LOG -DNO_STACK_TRACE -DNO_MEM_CONTEXT
coverage: coverage:
common/error: full common/error: full
@@ -53,7 +45,7 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: assert-on - name: assert-on
total: 2 total: 2
define: -DNO_LOG define: -DNO_LOG -DNO_STACK_TRACE -DNO_MEM_CONTEXT
coverage: coverage:
common/assert: noCode common/assert: noCode
@@ -61,19 +53,19 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: assert-off - name: assert-off
total: 2 total: 2
define: -DNDEBUG -DNO_LOG define: -DNDEBUG -DNO_LOG -DNO_STACK_TRACE -DNO_MEM_CONTEXT
debugUnitSuppress: true debugUnitSuppress: true
coverage: coverage:
common/assert: noCode common/assert: noCode
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: fork - name: stack-trace
total: 1 total: 4
define: -DNO_LOG define: -DNO_LOG -DNO_STACK_TRACE -DNO_MEM_CONTEXT
coverage: coverage:
common/fork: full common/stackTrace: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: mem-context - name: mem-context
@@ -83,20 +75,36 @@ unit:
coverage: coverage:
common/memContext: full common/memContext: full
# ----------------------------------------------------------------------------------------------------------------------------
- name: time
total: 2
define: -DNO_ERROR -DNO_LOG
coverage:
common/time: full
# ----------------------------------------------------------------------------------------------------------------------------
- name: fork
total: 1
define: -DNO_LOG
coverage:
common/fork: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: log - name: log
total: 5 total: 5
define: -DNO_LOG define: -DIN_LOG
coverage: coverage:
common/log: full common/log: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: debug-on - name: debug-on
total: 2 total: 4
coverage: coverage:
common/debug: noCode common/debug: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: debug-off - name: debug-off
@@ -105,7 +113,7 @@ unit:
debugUnitSuppress: true debugUnitSuppress: true
coverage: coverage:
common/debug: noCode common/debug: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: lock - name: lock
@@ -135,6 +143,13 @@ unit:
coverage: coverage:
common/wait: full common/wait: full
# ----------------------------------------------------------------------------------------------------------------------------
- name: type-convert
total: 8
coverage:
common/type/convert: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: type-list - name: type-list
total: 3 total: 3
@@ -144,14 +159,14 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: type-string - name: type-string
total: 11 total: 13
coverage: coverage:
common/type/string: full common/type/string: full
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: type-string-list - name: type-string-list
total: 8 total: 9
coverage: coverage:
common/type/stringList: full common/type/stringList: full
@@ -165,7 +180,7 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: type-variant - name: type-variant
total: 7 total: 8
coverage: coverage:
common/type/variant: full common/type/variant: full

View File

@@ -83,8 +83,12 @@ full backup - create pg_stat link, pg_clog dir (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --manifest-save-threshold=3 --buffer-size=16384 --checksum-page --process-max=1 --repo1-type=cifs --type=full --stanza=db backup > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --manifest-save-threshold=3 --buffer-size=16384 --checksum-page --process-max=1 --repo1-type=cifs --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=16384 --checksum-page --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --manifest-save-threshold=3 --no-online --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --repo1-type=cifs --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=16384 --checksum-page --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --manifest-save-threshold=3 --no-online --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --repo1-type=cifs --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -292,8 +296,10 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <f
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
@@ -324,10 +330,16 @@ P00 DEBUG: Storage::Local->list=>: stryFileList = ([BACKUP-FULL-1])
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-1] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-1]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -472,21 +484,33 @@ stop all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 INFO: sent term signal to process [PROCESS-ID] P00 INFO: sent term signal to process [PROCESS-ID]
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - abort backup - local (db-master host) full backup - abort backup - local (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -563,8 +587,12 @@ full backup - global stop (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -574,42 +602,67 @@ P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBu
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 ERROR: [062]: stop file exists for all stanzas P00 ERROR: [062]: stop file exists for all stanzas
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 62 P00 DEBUG: Main::mainCleanup(): iExitCode = 62
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: aborted with exception [062] P00 INFO: backup command end: aborted with exception [062]
P00 DEBUG: common/exit::exitSafe: => 62
P00 DEBUG: main::main: => 62
stop db stanza (db-master host) stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stop db stanza (db-master host) stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 WARN: stop file already exists for stanza db P00 WARN: stop file already exists for stanza db
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - stanza stop (db-master host) full backup - stanza stop (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -619,45 +672,78 @@ P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBu
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 ERROR: [062]: stop file exists for stanza db P00 ERROR: [062]: stop file exists for stanza db
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 62 P00 DEBUG: Main::mainCleanup(): iExitCode = 62
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: aborted with exception [062] P00 INFO: backup command end: aborted with exception [062]
P00 DEBUG: common/exit::exitSafe: => 62
P00 DEBUG: main::main: => 62
start db stanza (db-master host) start db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
start all stanzas (db-master host) start all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
start all stanzas (db-master host) start all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 WARN: stop file does not exist P00 WARN: stop file does not exist
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - resume (db-master host) full backup - resume (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --force --checksum-page --type=full --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --force --checksum-page --type=full --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --checksum-page --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --checksum-page --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -861,8 +947,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/r
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
@@ -893,10 +981,16 @@ P00 DEBUG: Storage::Local->list=>: stryFileList = ([BACKUP-FULL-2])
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -1043,6 +1137,8 @@ restore delta, backup '[BACKUP-FULL-2]' - add and delete files (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --set=[BACKUP-FULL-2] --link-all --stanza=db restore > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --set=[BACKUP-FULL-2] --link-all --stanza=db restore
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: restore command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --link-all --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --set=[BACKUP-FULL-2] --stanza=db P00 INFO: restore command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --link-all --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --set=[BACKUP-FULL-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -1338,10 +1434,16 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/d
P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base/backup.manifest P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base/backup.manifest
P00 DEBUG: Storage::Local->remove=>: bRemoved = true P00 DEBUG: Storage::Local->remove=>: bRemoved = true
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: restore command end: completed successfully P00 INFO: restore command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf + supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf
---------------------------------------------------------------- ----------------------------------------------------------------
@@ -1725,8 +1827,12 @@ incr backup - add tablespace 1 (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --test --stanza=db backup > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --test --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -1907,8 +2013,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/r
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
@@ -1947,10 +2055,16 @@ P00 DEBUG: Backup::Info->current=>: bTest = true
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -2091,8 +2205,12 @@ incr backup - resume and add tablespace 2 (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --process-max=1 --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --process-max=1 --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/db-master/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -2317,8 +2435,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/r
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/db-master/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
@@ -2357,10 +2477,16 @@ P00 DEBUG: Backup::Info->current=>: bTest = true
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -2848,6 +2974,8 @@ restore, backup '[BACKUP-DIFF-2]', remap - remap all paths (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --set=[BACKUP-DIFF-2] --stanza=db restore > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --set=[BACKUP-DIFF-2] --stanza=db restore
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: restore command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base-2 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --set=[BACKUP-DIFF-2] --stanza=db --tablespace-map=1=[TEST_PATH]/db-master/db/tablespace/ts1-2 --tablespace-map=2=[TEST_PATH]/db-master/db/tablespace/ts2-2 P00 INFO: restore command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base-2 --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --set=[BACKUP-DIFF-2] --stanza=db --tablespace-map=1=[TEST_PATH]/db-master/db/tablespace/ts1-2 --tablespace-map=2=[TEST_PATH]/db-master/db/tablespace/ts2-2
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -3143,10 +3271,16 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/d
P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base-2/backup.manifest P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base-2/backup.manifest
P00 DEBUG: Storage::Local->remove=>: bRemoved = true P00 DEBUG: Storage::Local->remove=>: bRemoved = true
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base-2 P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base-2
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: restore command end: completed successfully P00 INFO: restore command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/db/base-2/recovery.conf + supplemental file: [TEST_PATH]/db-master/db/base-2/recovery.conf
------------------------------------------------------------------ ------------------------------------------------------------------

View File

@@ -71,8 +71,12 @@ full backup - create pg_stat link, pg_clog dir (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --manifest-save-threshold=3 --protocol-timeout=2 --db-timeout=1 --cmd-ssh=/usr/bin/ssh --pg1-port=9999 --pg1-socket-path =/test_socket_path --buffer-size=16384 --checksum-page --process-max=1 --repo1-type=cifs --type=full --stanza=db backup > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --manifest-save-threshold=3 --protocol-timeout=2 --db-timeout=1 --cmd-ssh=/usr/bin/ssh --pg1-port=9999 --pg1-socket-path =/test_socket_path --buffer-size=16384 --checksum-page --process-max=1 --repo1-type=cifs --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=16384 --checksum-page --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=1 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --manifest-save-threshold=3 --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --pg1-port=9999 --pg1-socket-path==/test_socket_path --process-max=1 --protocol-timeout=2 --repo1-path=[TEST_PATH]/backup/repo --repo1-type=cifs --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=16384 --checksum-page --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=1 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --manifest-save-threshold=3 --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --pg1-port=9999 --pg1-socket-path==/test_socket_path --process-max=1 --protocol-timeout=2 --repo1-path=[TEST_PATH]/backup/repo --repo1-type=cifs --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -284,8 +288,10 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <f
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
@@ -316,10 +322,16 @@ P00 DEBUG: Storage::Local->list=>: stryFileList = ([BACKUP-FULL-1])
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-1] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-1]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -482,21 +494,33 @@ stop all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2]
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 INFO: sent term signal to process [PROCESS-ID] P00 INFO: sent term signal to process [PROCESS-ID]
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - abort backup - local (backup host) full backup - abort backup - local (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -589,18 +613,27 @@ P00 TEST: PgBaCkReStTeSt-BACKUP-START-PgBaCkReStTeSt
P00 DEBUG: Protocol::Helper::protocolGet(): bCache = <true>, iProcessIdx = [undef], iRemoteIdx = 1, strBackRestBin = [undef], strCommand = <backup>, strRemoteType = db P00 DEBUG: Protocol::Helper::protocolGet(): bCache = <true>, iProcessIdx = [undef], iRemoteIdx = 1, strBackRestBin = [undef], strCommand = <backup>, strRemoteType = db
P00 DEBUG: Protocol::Helper::protocolGet: found cached protocol P00 DEBUG: Protocol::Helper::protocolGet: found cached protocol
P00 ERROR: [063]: remote process on 'db-master' terminated unexpectedly [063] P00 ERROR: [063]: remote process on 'db-master' terminated unexpectedly [063]
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 63 P00 DEBUG: Main::mainCleanup(): iExitCode = 63
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = db P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = db
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: terminated on signal from child process P00 INFO: backup command end: terminated on signal from child process
P00 DEBUG: common/exit::exitSafe: => 63
P00 DEBUG: main::main: => 63
full backup - global stop (backup host) full backup - global stop (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -642,42 +675,67 @@ P00 DEBUG: Protocol::Remote::Master->new(): iBufferMax = 4194304, iCompress
P00 DEBUG: Protocol::Command::Master->new(): iBufferMax = 4194304, iCompressLevel = 3, iCompressLevelNetwork = 1, iProtocolTimeout = 60, strCommand = ssh -o LogLevel=error -o Compression=no -o PasswordAuthentication=no [USER-1]@db-master '[BACKREST-BIN] --buffer-size=4194304 --command=backup --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --type=db remote', strId = remote process on 'db-master', strName = remote P00 DEBUG: Protocol::Command::Master->new(): iBufferMax = 4194304, iCompressLevel = 3, iCompressLevelNetwork = 1, iProtocolTimeout = 60, strCommand = ssh -o LogLevel=error -o Compression=no -o PasswordAuthentication=no [USER-1]@db-master '[BACKREST-BIN] --buffer-size=4194304 --command=backup --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --type=db remote', strId = remote process on 'db-master', strName = remote
P00 ERROR: [062]: raised from remote process on 'db-master': stop file exists for all stanzas P00 ERROR: [062]: raised from remote process on 'db-master': stop file exists for all stanzas
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 62 P00 DEBUG: Main::mainCleanup(): iExitCode = 62
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: aborted with exception [062] P00 INFO: backup command end: aborted with exception [062]
P00 DEBUG: common/exit::exitSafe: => 62
P00 DEBUG: main::main: => 62
stop db stanza (db-master host) stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stop db stanza (db-master host) stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 WARN: stop file already exists for stanza db P00 WARN: stop file already exists for stanza db
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - stanza stop (backup host) full backup - stanza stop (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -719,58 +777,99 @@ P00 DEBUG: Protocol::Remote::Master->new(): iBufferMax = 4194304, iCompress
P00 DEBUG: Protocol::Command::Master->new(): iBufferMax = 4194304, iCompressLevel = 3, iCompressLevelNetwork = 1, iProtocolTimeout = 60, strCommand = ssh -o LogLevel=error -o Compression=no -o PasswordAuthentication=no [USER-1]@db-master '[BACKREST-BIN] --buffer-size=4194304 --command=backup --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --type=db remote', strId = remote process on 'db-master', strName = remote P00 DEBUG: Protocol::Command::Master->new(): iBufferMax = 4194304, iCompressLevel = 3, iCompressLevelNetwork = 1, iProtocolTimeout = 60, strCommand = ssh -o LogLevel=error -o Compression=no -o PasswordAuthentication=no [USER-1]@db-master '[BACKREST-BIN] --buffer-size=4194304 --command=backup --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --type=db remote', strId = remote process on 'db-master', strName = remote
P00 ERROR: [062]: raised from remote process on 'db-master': stop file exists for stanza db P00 ERROR: [062]: raised from remote process on 'db-master': stop file exists for stanza db
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 62 P00 DEBUG: Main::mainCleanup(): iExitCode = 62
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: aborted with exception [062] P00 INFO: backup command end: aborted with exception [062]
P00 DEBUG: common/exit::exitSafe: => 62
P00 DEBUG: main::main: => 62
start db stanza (db-master host) start db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
start all stanzas (db-master host) start all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2]
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
start all stanzas (db-master host) start all stanzas (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2]
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 WARN: stop file does not exist P00 WARN: stop file does not exist
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stop all stanzas (backup host) stop all stanzas (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --force stop > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --force stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --repo1-path=[TEST_PATH]/backup/repo P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --repo1-path=[TEST_PATH]/backup/repo
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
P00 INFO: sent term signal to process [PROCESS-ID] P00 INFO: sent term signal to process [PROCESS-ID]
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - abort backup - remote (backup host) full backup - abort backup - remote (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup --test --test-delay=5 --test-point=backup-start=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=5 --test-point=backup-start=y --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -871,8 +970,12 @@ full backup - global stop (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --type=full --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -882,26 +985,43 @@ P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBu
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 ERROR: [062]: stop file exists for all stanzas P00 ERROR: [062]: stop file exists for all stanzas
P00 DEBUG: common/exit::exitSafe: (result: 0, error: true, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 62 P00 DEBUG: Main::mainCleanup(): iExitCode = 62
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: backup command end: aborted with exception [062] P00 INFO: backup command end: aborted with exception [062]
P00 DEBUG: common/exit::exitSafe: => 62
P00 DEBUG: main::main: => 62
start all stanzas (backup host) start all stanzas (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf start > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf start
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --repo1-path=[TEST_PATH]/backup/repo P00 INFO: start command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --repo1-path=[TEST_PATH]/backup/repo
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: start command end: completed successfully P00 INFO: start command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
full backup - resume (backup host) full backup - resume (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --force --checksum-page --type=full --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --force --checksum-page --type=full --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --checksum-page --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y --type=full P00 INFO: backup command begin [BACKREST-VERSION]: --checksum-page --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y --type=full
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -1102,8 +1222,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
@@ -1134,10 +1256,16 @@ P00 DEBUG: Storage::Local->list=>: stryFileList = ([BACKUP-FULL-2])
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -1304,6 +1432,8 @@ restore delta, backup '[BACKUP-FULL-2]' - add and delete files (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --set=[BACKUP-FULL-2] --link-all --cmd-ssh=/usr/bin/ssh --stanza=db restore > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --set=[BACKUP-FULL-2] --link-all --cmd-ssh=/usr/bin/ssh --stanza=db restore
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: restore command begin [BACKREST-VERSION]: --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --link-all --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --set=[BACKUP-FULL-2] --stanza=db P00 INFO: restore command begin [BACKREST-VERSION]: --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --link-all --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --set=[BACKUP-FULL-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
@@ -1539,12 +1669,18 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/d
P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base/backup.manifest P00 DEBUG: Storage::Local->remove(): bIgnoreMissing = <true>, bRecurse = <false>, xstryPathFileExp = [TEST_PATH]/db-master/db/base/backup.manifest
P00 DEBUG: Storage::Local->remove=>: bRemoved = true P00 DEBUG: Storage::Local->remove=>: bRemoved = true
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/db-master/db/base
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: restore command end: completed successfully P00 INFO: restore command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf + supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf
---------------------------------------------------------------- ----------------------------------------------------------------
@@ -1757,8 +1893,12 @@ incr backup - add tablespace 1 (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --test --stanza=db backup > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --test --stanza=db backup
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -1936,8 +2076,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
@@ -1976,10 +2118,16 @@ P00 DEBUG: Backup::Info->current=>: bTest = true
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------
@@ -2140,8 +2288,12 @@ incr backup - resume and add tablespace 2 (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --process-max=1 --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --process-max=1 --stanza=db backup --test --test-delay=0.2 --test-point=backup-resume=y
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y P00 INFO: backup command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --no-online --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-master/db/base --process-max=1 --protocol-timeout=60 --repo1-path=[TEST_PATH]/backup/repo --stanza=db --start-fast --test --test-delay=0.2 --test-point=backup-resume=y
P00 DEBUG: common/lock::lockAcquire: (lockPath: {"[TEST_PATH]/backup/lock"}, stanza: {"db"}, lockType: 1, lockTimeout: 0, failOnNoLock: true)
P00 DEBUG: common/lock::lockAcquire: => true
P00 WARN: option repo1-retention-full is not set, the repository may run out of space P00 WARN: option repo1-retention-full is not set, the repository may run out of space
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum. HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
@@ -2363,8 +2515,10 @@ P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo
P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy P00 DEBUG: Storage::Local->openWrite(): bAtomic = <false>, bPathCreate = <false>, lTimestamp = [undef], rhyFilter = [undef], strCipherPass = [undef], strGroup = [undef], strMode = <0640>, strUser = [undef], xFileExp = [TEST_PATH]/backup/repo/backup/db/backup.info.copy
P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db P00 DEBUG: Storage::Local->pathSync(): strPathExp = [TEST_PATH]/backup/repo/backup/db
P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP> P00 DEBUG: Storage::Local->pathSync(): strPathExp = <REPO:BACKUP>
P00 DEBUG: perl/exec::perlExec: => 0
P00 INFO: backup command end: completed successfully P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin P00 INFO: expire command begin
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Local->pathExists(): strPathExp = P00 DEBUG: Storage::Local->pathExists(): strPathExp =
P00 DEBUG: Storage::Local->pathExists=>: bExists = true P00 DEBUG: Storage::Local->pathExists=>: bExists = true
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
@@ -2403,10 +2557,16 @@ P00 DEBUG: Backup::Info->current=>: bTest = true
P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2] P00 DEBUG: Backup::Info->current(): strBackup = [BACKUP-FULL-2]
P00 DEBUG: Backup::Info->current=>: bTest = true P00 DEBUG: Backup::Info->current=>: bTest = true
P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired P00 INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => true
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: expire command end: completed successfully P00 INFO: expire command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
+ supplemental file: [TEST_PATH]/db-master/pgbackrest.conf + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf
---------------------------------------------------------- ----------------------------------------------------------

View File

@@ -68,6 +68,8 @@ db-version="9.4"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --log-level-console=debug [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --log-level-console=debug [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -105,14 +107,23 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = true, bPathCreate = true,
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000001 P00 INFO: pushed WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: command/archive/get/get::cmdArchiveGet: (void)
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG) P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG)
P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001 P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
@@ -149,10 +160,17 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = false, bPathCreate = <fal
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0 P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0
P00 INFO: got WAL segment 000000010000000100000001 P00 INFO: got WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: command/archive/get/get::cmdArchiveGet: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-get command end: completed successfully P00 INFO: archive-get command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------

View File

@@ -60,6 +60,8 @@ db-version="9.4"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --cmd-ssh=/usr/bin/ssh --log-level-console=debug [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --cmd-ssh=/usr/bin/ssh --log-level-console=debug [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -87,16 +89,25 @@ P00 DEBUG: Protocol::Storage::Remote->openWrite(): rhParam = [hash], strFil
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000001 P00 INFO: pushed WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: command/archive/get/get::cmdArchiveGet: (void)
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG) P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG)
P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001 P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
@@ -124,12 +135,19 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = false, bPathCreate = <fal
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0 P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0
P00 INFO: got WAL segment 000000010000000100000001 P00 INFO: got WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: command/archive/get/get::cmdArchiveGet: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-get command end: completed successfully P00 INFO: archive-get command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------

View File

@@ -178,6 +178,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -215,10 +217,16 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = true, bPathCreate = true,
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000001 P00 INFO: pushed WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-create db - fail on archive info file missing from non-empty dir (db-master host) stanza-create db - fail on archive info file missing from non-empty dir (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
@@ -425,6 +433,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -462,10 +472,16 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = true, bPathCreate = true,
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000002 P00 INFO: pushed WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -516,6 +532,9 @@ db-version="9.4"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: command/archive/get/get::cmdArchiveGet: (void)
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG) P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG)
P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002 P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
@@ -552,10 +571,17 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = false, bPathCreate = <fal
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0 P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0
P00 INFO: got WAL segment 000000010000000100000002 P00 INFO: got WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: command/archive/get/get::cmdArchiveGet: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-get command end: completed successfully P00 INFO: archive-get command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -958,13 +984,21 @@ stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-delete db - successfully delete the stanza (db-master host) stanza-delete db - successfully delete the stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete

View File

@@ -202,6 +202,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -229,12 +231,18 @@ P00 DEBUG: Protocol::Storage::Remote->openWrite(): rhParam = [hash], strFil
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000001 P00 INFO: pushed WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-create db - gunzip fail on forced stanza-create (backup host) stanza-create db - gunzip fail on forced stanza-create (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail --no-online --force stanza-create > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail --no-online --force stanza-create
@@ -293,6 +301,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -320,12 +330,18 @@ P00 DEBUG: Protocol::Storage::Remote->openWrite(): rhParam = [hash], strFil
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000002 P00 INFO: pushed WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -382,6 +398,9 @@ db-version="9.4"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: command/archive/get/get::cmdArchiveGet: (void)
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG) P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG)
P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002 P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
@@ -409,12 +428,19 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = false, bPathCreate = <fal
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0 P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0
P00 INFO: got WAL segment 000000010000000100000002 P00 INFO: got WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: command/archive/get/get::cmdArchiveGet: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup P00 DEBUG: Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = backup
P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0 P00 DEBUG: Protocol::Command::Master->close=>: iExitStatus = 0
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-get command end: completed successfully P00 INFO: archive-get command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -792,13 +818,21 @@ stop db stanza (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/backup/repo --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --no-log-timestamp --pg1-host=db-master --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-master/pgbackrest.conf --pg1-host-user=[USER-1] --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/backup/repo --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-delete db - successfully delete the stanza (backup host) stanza-delete db - successfully delete the stanza (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete > [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete

View File

@@ -178,6 +178,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -215,10 +217,16 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = true, bPathCreate = true,
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000001 P00 INFO: pushed WAL segment 000000010000000100000001
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-create db - fail on archive info file missing from non-empty dir (db-master host) stanza-create db - fail on archive info file missing from non-empty dir (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
@@ -400,6 +408,8 @@ db-version="9.3"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 P00 DEBUG: Archive::Push::Push->process(): strWalPathFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
@@ -437,10 +447,16 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = true, bPathCreate = true,
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef] P00 DEBUG: Archive::Push::File::archivePushFile=>: strWarning = [undef]
P00 INFO: pushed WAL segment 000000010000000100000002 P00 INFO: pushed WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-push command end: completed successfully P00 INFO: archive-push command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -491,6 +507,9 @@ db-version="9.4"
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: command/archive/get/get::cmdArchiveGet: (void)
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG) P00 DEBUG: Archive::Get::Get->process(): rstryCommandArg = (000000010000000100000002, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG)
P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002 P00 DEBUG: Archive::Get::File::archiveGetFile(): bAtomic = false, strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false> P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
@@ -527,10 +546,17 @@ P00 DEBUG: Storage::Local->openWrite(): bAtomic = false, bPathCreate = <fal
P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object] P00 DEBUG: Storage::Base->copy(): xDestinationFile = [object], xSourceFile = [object]
P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0 P00 DEBUG: Archive::Get::File::archiveGetFile=>: iResult = 0
P00 INFO: got WAL segment 000000010000000100000002 P00 INFO: got WAL segment 000000010000000100000002
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: command/archive/get/get::cmdArchiveGet: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: archive-get command end: completed successfully P00 INFO: archive-get command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
@@ -945,13 +971,21 @@ stop db stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-log-timestamp --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-s3-verify-ssl --repo1-type=s3 --stanza=db
P00 DEBUG: config/load::cfgLoad: => void
P00 DEBUG: perl/exec::perlExec: (void)
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
P00 DEBUG: perl/exec::perlExec: => 0
P00 DEBUG: common/exit::exitSafe: (result: 0, error: false, signalType: 0)
P00 DEBUG: common/lock::lockRelease: (failOnNoLock: false)
P00 DEBUG: common/lock::lockRelease: => false
P00 DEBUG: Main::mainCleanup(): iExitCode = 0 P00 DEBUG: Main::mainCleanup(): iExitCode = 0
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0 P00 DEBUG: Protocol::Helper::protocolDestroy=>: iExitStatus = 0
P00 INFO: stop command end: completed successfully P00 INFO: stop command end: completed successfully
P00 DEBUG: common/exit::exitSafe: => 0
P00 DEBUG: main::main: => 0
stanza-delete db - successfully delete the stanza (db-master host) stanza-delete db - successfully delete the stanza (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail stanza-delete

View File

@@ -69,6 +69,7 @@ sub new
$self->{bValgrindUnit}, $self->{bValgrindUnit},
$self->{bCoverageUnit}, $self->{bCoverageUnit},
$self->{bOptimize}, $self->{bOptimize},
$self->{bBackTrace},
$self->{bProfile}, $self->{bProfile},
$self->{bDebug}, $self->{bDebug},
) = ) =
@@ -94,6 +95,7 @@ sub new
{name => 'bValgrindUnit'}, {name => 'bValgrindUnit'},
{name => 'bCoverageUnit'}, {name => 'bCoverageUnit'},
{name => 'bOptimize'}, {name => 'bOptimize'},
{name => 'bBackTrace'},
{name => 'bProfile'}, {name => 'bProfile'},
{name => 'bDebug'}, {name => 'bDebug'},
); );
@@ -360,8 +362,10 @@ sub run
" -Wformat=2 -Wformat-nonliteral \\\n" . " -Wformat=2 -Wformat-nonliteral \\\n" .
" `perl -MExtUtils::Embed -e ccopts`\n" . " `perl -MExtUtils::Embed -e ccopts`\n" .
"LDFLAGS=-lcrypto" . (vmCoverage($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit} ? " -lgcov" : '') . "LDFLAGS=-lcrypto" . (vmCoverage($self->{oTest}->{&TEST_VM}) && $self->{bCoverageUnit} ? " -lgcov" : '') .
(vmWithBackTrace($self->{oTest}->{&TEST_VM}) && $self->{bBackTrace} ? ' -lbacktrace' : '') .
" `perl -MExtUtils::Embed -e ldopts`\n" . " `perl -MExtUtils::Embed -e ldopts`\n" .
'TESTFLAGS=' . ($self->{oTest}->{&TEST_DEBUG_UNIT_SUPPRESS} ? '' : "-DDEBUG_UNIT") . 'TESTFLAGS=' . ($self->{oTest}->{&TEST_DEBUG_UNIT_SUPPRESS} ? '' : "-DDEBUG_UNIT") .
(vmWithBackTrace($self->{oTest}->{&TEST_VM}) && $self->{bBackTrace} ? ' -DWITH_BACKTRACE' : '') .
($self->{oTest}->{&TEST_CDEF} ? " $self->{oTest}->{&TEST_CDEF}" : '') . ($self->{oTest}->{&TEST_CDEF} ? " $self->{oTest}->{&TEST_CDEF}" : '') .
($self->{bDebug} ? '' : " -DNDEBUG") . ($self->{bDebug} ? '' : " -DNDEBUG") .
"\n" . "\n" .

View File

@@ -1,6 +1,7 @@
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Harness for Loading Test Configurations Harness for Loading Test Configurations
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/harnessDebug.h"
#include "common/logTest.h" #include "common/logTest.h"
#include "config/load.h" #include "config/load.h"
@@ -15,7 +16,14 @@ log files, acquire locks, etc.
void void
harnessCfgLoad(unsigned int argListSize, const char *argList[]) harnessCfgLoad(unsigned int argListSize, const char *argList[])
{ {
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(UINT, argListSize);
FUNCTION_HARNESS_PARAM(CHARPY, argList);
FUNCTION_HARNESS_END();
configParse(argListSize, argList); configParse(argListSize, argList);
logInit(logLevelInfo, logLevelOff, logLevelDebug, false); logInit(logLevelInfo, logLevelOff, logLevelDebug, false);
cfgLoadUpdateOption(); cfgLoadUpdateOption();
FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -0,0 +1,58 @@
/***********************************************************************************************************************************
C Debug Harness
***********************************************************************************************************************************/
#ifndef TEST_COMMON_HARNESS_DEBUG_H
#define TEST_COMMON_HARNESS_DEBUG_H
#ifdef NO_STACK_TRACE
#define FUNCTION_HARNESS_INIT(exe)
#define FUNCTION_HARNESS_BEGIN()
#define FUNCTION_HARNESS_PARAM(typeMacroPrefix, param)
#define FUNCTION_HARNESS_END()
#define FUNCTION_HARNESS_VOID()
#define FUNCTION_HARNESS_ASSERT(condition)
#define FUNCTION_HARNESS_RESULT(typeMacroPrefix, result) \
return result
#define FUNCTION_HARNESS_RESULT_VOID();
#else
#include "common/debug.h"
#ifdef WITH_BACKTRACE
#define FUNCTION_HARNESS_INIT(exe) \
stackTraceInit(exe)
#else
#define FUNCTION_HARNESS_INIT(exe)
#endif
#define FUNCTION_HARNESS_BEGIN() \
STACK_TRACE_PUSH(logLevelDebug); \
stackTraceParamLog()
#define FUNCTION_HARNESS_PARAM(typeMacroPrefix, param) \
FUNCTION_DEBUG_PARAM(typeMacroPrefix, param)
#define FUNCTION_HARNESS_END()
#define FUNCTION_HARNESS_VOID() \
FUNCTION_HARNESS_BEGIN(); \
FUNCTION_HARNESS_END()
#define FUNCTION_HARNESS_ASSERT(condition) \
do \
{ \
if (!(condition)) \
THROW_FMT(AssertError, "function harness assertion '%s' failed", #condition); \
} \
while (0)
#define FUNCTION_HARNESS_RESULT(typeMacroPrefix, result) \
STACK_TRACE_POP(); \
return result \
#define FUNCTION_HARNESS_RESULT_VOID() \
STACK_TRACE_POP();
#endif
#endif

View File

@@ -5,6 +5,7 @@ C Test Harness
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "common/harnessDebug.h"
#include "common/harnessTest.h" #include "common/harnessTest.h"
#include "common/logTest.h" #include "common/logTest.h"
@@ -21,21 +22,55 @@ static int testRun = 0;
static int testTotal = 0; static int testTotal = 0;
static bool testFirst = true; static bool testFirst = true;
static const char *testExeData = NULL;
static const char *testPathData = NULL; static const char *testPathData = NULL;
/***********************************************************************************************************************************
Get and set the test exe
***********************************************************************************************************************************/
const char *
testExe()
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testExeData);
}
void
testExeSet(const char *testExe)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testExe);
FUNCTION_HARNESS_ASSERT(testExe != NULL);
FUNCTION_HARNESS_END();
testExeData = testExe;
FUNCTION_HARNESS_RESULT_VOID();
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Get and set the test path, i.e., the path where this test should write its files Get and set the test path, i.e., the path where this test should write its files
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
const char * const char *
testPath() testPath()
{ {
return testPathData; FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testPathData);
} }
void void
testPathSet(const char *testPathParam) testPathSet(const char *testPath)
{ {
testPathData = testPathParam; FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testPath);
FUNCTION_HARNESS_ASSERT(testPath != NULL);
FUNCTION_HARNESS_END();
testPathData = testPath;
FUNCTION_HARNESS_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -44,6 +79,11 @@ testAdd - add a new test
void void
testAdd(int run, bool selected) testAdd(int run, bool selected)
{ {
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(INT, run);
FUNCTION_HARNESS_PARAM(BOOL, selected);
FUNCTION_HARNESS_END();
if (run != testTotal + 1) if (run != testTotal + 1)
{ {
fprintf(stderr, "ERROR: test run %d is not in order\n", run); fprintf(stderr, "ERROR: test run %d is not in order\n", run);
@@ -53,6 +93,8 @@ testAdd(int run, bool selected)
testList[testTotal].selected = selected; testList[testTotal].selected = selected;
testTotal++; testTotal++;
FUNCTION_HARNESS_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -61,14 +103,23 @@ testBegin - should this test run?
bool bool
testBegin(const char *name) testBegin(const char *name)
{ {
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, name);
FUNCTION_HARNESS_ASSERT(name != NULL);
FUNCTION_HARNESS_END();
bool result = false;
testRun++; testRun++;
if (testList[testRun - 1].selected) if (testList[testRun - 1].selected)
{ {
#ifndef NO_LOG #ifndef NO_LOG
#ifndef IN_LOG
// Make sure there is nothing untested left in the log // Make sure there is nothing untested left in the log
if (!testFirst) if (!testFirst)
testLogFinal(); testLogFinal();
#endif
#endif #endif
// No longer the first test // No longer the first test
testFirst = false; testFirst = false;
@@ -80,14 +131,16 @@ testBegin(const char *name)
fflush(stdout); fflush(stdout);
#ifndef NO_LOG #ifndef NO_LOG
#ifndef IN_LOG
// Initialize logging // Initialize logging
testLogInit(); testLogInit();
#endif
#endif #endif
return true; result = true;
} }
return false; FUNCTION_HARNESS_RESULT(BOOL, result);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -96,9 +149,13 @@ testComplete - make sure all expected tests ran
void void
testComplete() testComplete()
{ {
FUNCTION_HARNESS_VOID();
#ifndef NO_LOG #ifndef NO_LOG
#ifndef IN_LOG
// Make sure there is nothing untested left in the log // Make sure there is nothing untested left in the log
testLogFinal(); testLogFinal();
#endif
#endif #endif
// Check that all tests ran // Check that all tests ran
@@ -108,4 +165,6 @@ testComplete()
fflush(stderr); fflush(stderr);
exit(255); exit(255);
} }
FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -16,8 +16,11 @@ void testAdd(int run, bool selected);
bool testBegin(const char *name); bool testBegin(const char *name);
void testComplete(); void testComplete();
const char *testExe();
void testExeSet(const char *testExe);
const char *testPath(); const char *testPath();
void testPathSet(const char *testPathParam); void testPathSet(const char *testPath);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Convert a macro to a string -- handy for testing debug macros Convert a macro to a string -- handy for testing debug macros
@@ -53,8 +56,8 @@ Test that an expected error is actually thrown and error when it isn't
\ \
if (strcmp(errorMessage(), errorMessageExpected) != 0 || errorType() != &errorTypeExpected) \ if (strcmp(errorMessage(), errorMessageExpected) != 0 || errorType() != &errorTypeExpected) \
THROW_FMT( \ THROW_FMT( \
AssertError, "expected error %s, '%s' but got %s, '%s'", errorTypeName(&errorTypeExpected), errorMessageExpected, \ AssertError, "EXECTED %s: %s\n\nBUT GOT %s: %s\n\nTHROWN AT:\n%s", errorTypeName(&errorTypeExpected), \
errorName(), errorMessage()); \ errorMessageExpected, errorName(), errorMessage(), errorStackTrace()); \
} \ } \
TRY_END(); \ TRY_END(); \
\ \
@@ -153,8 +156,8 @@ parameters.
{ \ { \
/* No errors were expected so error */ \ /* No errors were expected so error */ \
THROW_FMT( \ THROW_FMT( \
AssertError, "statement '%s' threw error %s, '%s' but result <%s> expected", \ AssertError, "STATEMENT: %s\n\nTHREW %s: %s\n\nTHROWN AT:\n%s\n\nBUT EXPECTED RESULT:\n%s", \
#statement, errorName(), errorMessage(), TEST_RESULT_resultExpectedStr); \ #statement, errorName(), errorMessage(), errorStackTrace(), TEST_RESULT_resultExpectedStr); \
} \ } \
TRY_END(); \ TRY_END(); \
\ \

View File

@@ -3,11 +3,14 @@ Log Test Harness
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <regex.h>
#include "common/harnessTest.h" #include <stdio.h>
#include <string.h>
#include "common/log.h" #include "common/log.h"
#include "storage/helper.h"
#include "common/harnessDebug.h"
#include "common/harnessTest.h"
#ifndef NO_LOG #ifndef NO_LOG
@@ -19,8 +22,35 @@ static bool harnessLogInit = false;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Name of file where logs are stored for testing Name of file where logs are stored for testing
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
String *stdoutFile = NULL; static char stdoutFile[1024];
String *stderrFile = NULL; static char stderrFile[1024];
/***********************************************************************************************************************************
Buffer where log results are loaded for comparison purposes
***********************************************************************************************************************************/
char harnessLogBuffer[256 * 1024];
/***********************************************************************************************************************************
Open a log file -- centralized here for error handling
***********************************************************************************************************************************/
static int
harnessLogOpen(const char *logFile, int flags, int mode)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, logFile);
FUNCTION_HARNESS_PARAM(INT, flags);
FUNCTION_HARNESS_PARAM(INT, mode);
FUNCTION_HARNESS_ASSERT(logFile != NULL);
FUNCTION_HARNESS_END();
int result = open(logFile, flags, mode);
if (result == -1)
THROW_SYS_ERROR_FMT(FileOpenError, "unable to open log file '%s'", logFile);
FUNCTION_HARNESS_RESULT(INT, result);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Initialize log for testing Initialize log for testing
@@ -28,18 +58,61 @@ Initialize log for testing
void void
testLogInit() testLogInit()
{ {
FUNCTION_HARNESS_VOID();
if (!harnessLogInit) if (!harnessLogInit)
{ {
logInit(logLevelInfo, logLevelOff, logLevelOff, false); logInit(logLevelInfo, logLevelOff, logLevelOff, false);
stdoutFile = strNewFmt("%s/stdout.log", testPath()); snprintf(stdoutFile, sizeof(stdoutFile), "%s/stdout.log", testPath());
logHandleStdOut = open(strPtr(stdoutFile), O_WRONLY | O_CREAT | O_TRUNC, 0640); logHandleStdOut = harnessLogOpen(stdoutFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
stderrFile = strNewFmt("%s/stderr.log", testPath()); snprintf(stderrFile, sizeof(stderrFile), "%s/stderr.log", testPath());
logHandleStdErr = open(strPtr(stderrFile), O_WRONLY | O_CREAT | O_TRUNC, 0640); logHandleStdErr = harnessLogOpen(stderrFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
harnessLogInit = true; harnessLogInit = true;
} }
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Load log result from file into the log buffer
***********************************************************************************************************************************/
void
harnessLogLoad(const char *logFile)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, logFile);
FUNCTION_HARNESS_ASSERT(logFile != NULL);
FUNCTION_HARNESS_END();
harnessLogBuffer[0] = 0;
int handle = harnessLogOpen(logFile, O_RDONLY, 0);
size_t totalBytes = 0;
ssize_t actualBytes = 0;
do
{
actualBytes = read(handle, harnessLogBuffer, sizeof(harnessLogBuffer) - totalBytes);
if (actualBytes == -1)
THROW_SYS_ERROR_FMT(FileOpenError, "unable to read log file '%s'", logFile);
totalBytes += (size_t)actualBytes;
}
while (actualBytes != 0);
if (close(handle) == -1)
THROW_SYS_ERROR_FMT(FileOpenError, "unable to close log file '%s'", logFile);
// Remove final linefeed
harnessLogBuffer[totalBytes - 1] = 0;
FUNCTION_HARNESS_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -50,13 +123,67 @@ After the comparison the log is cleared so the next result can be compared.
void void
testLogResult(const char *expected) testLogResult(const char *expected)
{ {
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stdoutFile)))); FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, expected);
if (!strEqZ(actual, expected)) FUNCTION_HARNESS_ASSERT(expected != NULL);
THROW_FMT(AssertError, "\n\nexpected log:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expected, strPtr(actual)); FUNCTION_HARNESS_END();
harnessLogLoad(stdoutFile);
if (strcmp(harnessLogBuffer, expected) != 0)
THROW_FMT(AssertError, "\n\nexpected log:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expected, harnessLogBuffer);
close(logHandleStdOut); close(logHandleStdOut);
logHandleStdOut = open(strPtr(stdoutFile), O_WRONLY | O_CREAT | O_TRUNC, 0640); logHandleStdOut = harnessLogOpen(stdoutFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Compare log to a regexp
After the comparison the log is cleared so the next result can be compared.
***********************************************************************************************************************************/
void
testLogResultRegExp(const char *expression)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, expression);
FUNCTION_HARNESS_ASSERT(expression != NULL);
FUNCTION_HARNESS_END();
regex_t regExp;
TRY_BEGIN()
{
harnessLogLoad(stdoutFile);
// Compile the regexp and process errors
int result = 0;
if ((result = regcomp(&regExp, expression, REG_NOSUB | REG_EXTENDED)) != 0)
{
char buffer[4096];
regerror(result, NULL, buffer, sizeof(buffer));
THROW(FormatError, buffer);
}
// Do the match
if (regexec(&regExp, harnessLogBuffer, 0, NULL, 0) != 0)
THROW_FMT(AssertError, "\n\nexpected log regexp:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expression, harnessLogBuffer);
close(logHandleStdOut);
logHandleStdOut = harnessLogOpen(stdoutFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
}
FINALLY()
{
regfree(&regExp);
}
TRY_END();
FUNCTION_HARNESS_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -67,13 +194,21 @@ After the comparison the log is cleared so the next result can be compared.
void void
testLogErrResult(const char *expected) testLogErrResult(const char *expected)
{ {
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stderrFile)))); FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, expected);
if (!strEqZ(actual, expected)) FUNCTION_HARNESS_ASSERT(expected != NULL);
THROW_FMT(AssertError, "\n\nexpected error log:\n\n%s\n\nbut actual error log was:\n\n%s\n\n", expected, strPtr(actual)); FUNCTION_HARNESS_END();
harnessLogLoad(stderrFile);
if (strcmp(harnessLogBuffer, expected) != 0)
THROW_FMT(AssertError, "\n\nexpected error log:\n\n%s\n\nbut actual error log was:\n\n%s\n\n", expected, harnessLogBuffer);
close(logHandleStdErr); close(logHandleStdErr);
logHandleStdErr = open(strPtr(stderrFile), O_WRONLY | O_CREAT | O_TRUNC, 0640); logHandleStdErr = harnessLogOpen(stderrFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
FUNCTION_HARNESS_RESULT_VOID();
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@@ -82,15 +217,19 @@ Make sure nothing is left in the log after all tests have completed
void void
testLogFinal() testLogFinal()
{ {
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stdoutFile)))); FUNCTION_HARNESS_VOID();
if (!strEqZ(actual, "")) harnessLogLoad(stdoutFile);
THROW_FMT(AssertError, "\n\nexpected log to be empty but actual log was:\n\n%s\n\n", strPtr(actual));
actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stderrFile)))); if (strcmp(harnessLogBuffer, "") != 0)
THROW_FMT(AssertError, "\n\nexpected log to be empty but actual log was:\n\n%s\n\n", harnessLogBuffer);
if (!strEqZ(actual, "")) harnessLogLoad(stderrFile);
THROW_FMT(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", strPtr(actual));
if (strcmp(harnessLogBuffer, "") != 0)
THROW_FMT(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", harnessLogBuffer);
FUNCTION_HARNESS_RESULT_VOID();
} }
#endif #endif

View File

@@ -7,11 +7,10 @@ Log Test Harness
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#ifndef NO_LOG
void testLogInit(); void testLogInit();
void testLogResult(const char *expected); void testLogResult(const char *expected);
void testLogResultRegExp(const char *expression);
void testLogErrResult(const char *expected); void testLogErrResult(const char *expected);
void testLogFinal(); void testLogFinal();
#endif
#endif #endif

View File

@@ -11,6 +11,8 @@ Test Run
void void
testRun() testRun()
{ {
FUNCTION_HARNESS_VOID();
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("archiveAsyncStatus()")) if (testBegin("archiveAsyncStatus()"))
{ {
@@ -53,7 +55,7 @@ testRun()
storagePutNP( storagePutNP(
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
bufNewStr(strNew(BOGUS_STR "\nmessage"))); bufNewStr(strNew(BOGUS_STR "\nmessage")));
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, false), FormatError, "unable to convert str 'BOGUS' to int"); TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, false), FormatError, "unable to convert string 'BOGUS' to int");
storagePutNP(storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), NULL); storagePutNP(storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), NULL);
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file"); TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file");
@@ -143,4 +145,6 @@ testRun()
"000000070000000700000FFE|000000070000000700000FFF|000000070000000800000000|000000070000000800000001", "000000070000000700000FFE|000000070000000700000FFF|000000070000000800000000|000000070000000800000001",
"get range >= 11/1MB"); "get range >= 11/1MB");
} }
FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -13,6 +13,8 @@ Test Run
void void
testRun() testRun()
{ {
FUNCTION_HARNESS_VOID();
Storage *storageTest = storageNewP(strNew(testPath()), .write = true); Storage *storageTest = storageNewP(strNew(testPath()), .write = true);
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@@ -48,12 +50,15 @@ testRun()
"000000010000000100000001|000000010000000100000002|000000010000000100000003", "empty queue"); "000000010000000100000001|000000010000000100000002|000000010000000100000003", "empty queue");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
Buffer *walSegmentBuffer = bufNew(walSegmentSize);
memset(bufPtr(walSegmentBuffer), 0, walSegmentSize);
storagePutNP( storagePutNP(
storageNewWriteNP( storageNewWriteNP(
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE")), bufNew(walSegmentSize)); storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE")), walSegmentBuffer);
storagePutNP( storagePutNP(
storageNewWriteNP( storageNewWriteNP(
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF")), bufNew(walSegmentSize)); storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF")), walSegmentBuffer);
TEST_RESULT_STR( TEST_RESULT_STR(
strPtr(strLstJoin(queueNeed(strNew("0000000100000001000000FE"), false, queueSize, walSegmentSize, PG_VERSION_92), "|")), strPtr(strLstJoin(queueNeed(strNew("0000000100000001000000FE"), false, queueSize, walSegmentSize, PG_VERSION_92), "|")),
@@ -67,13 +72,13 @@ testRun()
walSegmentSize = 1024 * 1024; walSegmentSize = 1024 * 1024;
queueSize = walSegmentSize * 5; queueSize = walSegmentSize * 5;
storagePutNP(storageNewWriteNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/junk")), bufNew(16)); storagePutNP(storageNewWriteNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/junk")), bufNewStr(strNew("JUNK")));
storagePutNP( storagePutNP(
storageNewWriteNP( storageNewWriteNP(
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFE")), bufNew(walSegmentSize)); storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFE")), walSegmentBuffer);
storagePutNP( storagePutNP(
storageNewWriteNP( storageNewWriteNP(
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFF")), bufNew(walSegmentSize)); storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFF")), walSegmentBuffer);
TEST_RESULT_STR( TEST_RESULT_STR(
strPtr(strLstJoin(queueNeed(strNew("000000010000000A00000FFD"), true, queueSize, walSegmentSize, PG_VERSION_11), "|")), strPtr(strLstJoin(queueNeed(strNew("000000010000000A00000FFD"), true, queueSize, walSegmentSize, PG_VERSION_11), "|")),
@@ -106,7 +111,7 @@ testRun()
strLstAdd(argListTemp, walSegment); strLstAdd(argListTemp, walSegment);
harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp)); harnessCfgLoad(strLstSize(argListTemp), strLstPtr(argListTemp));
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "Path to copy WAL segment required"); TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "path to copy WAL segment required");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
String *controlFile = strNew("db/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL); String *controlFile = strNew("db/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL);
@@ -240,6 +245,8 @@ testRun()
strLstAddZ(argList, BOGUS_STR); strLstAddZ(argList, BOGUS_STR);
harnessCfgLoad(strLstSize(argList), strLstPtr(argList)); harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "extra parameters found"); TEST_ERROR(cmdArchiveGet(), ParamInvalidError, "extra parameters found");
} }
FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -9,6 +9,8 @@ Test Run
void void
testRun() testRun()
{ {
FUNCTION_HARNESS_VOID();
// Create default storage object for testing // Create default storage object for testing
Storage *storageTest = storageNewP(strNew(testPath()), .write = true); Storage *storageTest = storageNewP(strNew(testPath()), .write = true);
@@ -83,4 +85,6 @@ testRun()
cmdArchivePush(), ArchiveTimeoutError, cmdArchivePush(), ArchiveTimeoutError,
"unable to push WAL segment '000000010000000100000001' asynchronously after 1 second(s)"); "unable to push WAL segment '000000010000000100000001' asynchronously after 1 second(s)");
} }
FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -21,6 +21,8 @@ Test Run
void void
testRun() testRun()
{ {
FUNCTION_HARNESS_VOID();
// ----------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("blockCipherNew() and blockCipherFree()")) if (testBegin("blockCipherNew() and blockCipherFree()"))
{ {
@@ -30,9 +32,6 @@ testRun()
cipherBlockNew( cipherBlockNew(
cipherModeEncrypt, BOGUS_STR, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL), AssertError, cipherModeEncrypt, BOGUS_STR, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL), AssertError,
"unable to load cipher 'BOGUS'"); "unable to load cipher 'BOGUS'");
TEST_ERROR(
cipherBlockNew(cipherModeEncrypt, NULL, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL), AssertError,
"unable to load cipher '(null)'");
TEST_ERROR( TEST_ERROR(
cipherBlockNew( cipherBlockNew(
cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, BOGUS_STR), AssertError, cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, BOGUS_STR), AssertError,
@@ -159,7 +158,7 @@ testRun()
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
blockEncrypt = cipherBlockNew(cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL); blockEncrypt = cipherBlockNew(cipherModeEncrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL);
TEST_RESULT_INT(cipherBlockProcess(blockEncrypt, NULL, 0, encryptBuffer), 16, "process header"); TEST_RESULT_INT(cipherBlockProcess(blockEncrypt, decryptBuffer, 0, encryptBuffer), 16, "process header");
TEST_RESULT_INT(cipherBlockFlush(blockEncrypt, encryptBuffer + 16), 16, "flush remaining bytes"); TEST_RESULT_INT(cipherBlockFlush(blockEncrypt, encryptBuffer + 16), 16, "flush remaining bytes");
cipherBlockFree(blockEncrypt); cipherBlockFree(blockEncrypt);
@@ -200,7 +199,7 @@ testRun()
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
blockDecrypt = cipherBlockNew(cipherModeDecrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL); blockDecrypt = cipherBlockNew(cipherModeDecrypt, TEST_CIPHER, (unsigned char *)TEST_PASS, TEST_PASS_SIZE, NULL);
TEST_RESULT_INT(cipherBlockProcess(blockDecrypt, NULL, 0, decryptBuffer), 0, "no header processed"); TEST_RESULT_INT(cipherBlockProcess(blockDecrypt, encryptBuffer, 0, decryptBuffer), 0, "no header processed");
TEST_ERROR(cipherBlockFlush(blockDecrypt, decryptBuffer), CipherError, "cipher header missing"); TEST_ERROR(cipherBlockFlush(blockDecrypt, decryptBuffer), CipherError, "cipher header missing");
cipherBlockFree(blockDecrypt); cipherBlockFree(blockDecrypt);
@@ -217,5 +216,5 @@ testRun()
cipherBlockFree(blockDecrypt); cipherBlockFree(blockDecrypt);
} }
cipherFree(); FUNCTION_HARNESS_RESULT_VOID();
} }

View File

@@ -8,6 +8,8 @@ Test Run
void void
testRun() testRun()
{ {
FUNCTION_HARNESS_VOID();
// ----------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("randomBytes()")) if (testBegin("randomBytes()"))
{ {
@@ -24,9 +26,11 @@ testRun()
int nonZeroTotal = 0; int nonZeroTotal = 0;
for (unsigned int charIdx = 0; charIdx < bufferSize; charIdx++) for (unsigned int charIdx = 0; charIdx < bufferSize; charIdx++)
if (buffer[charIdx] != 0) if (buffer[charIdx] != 0) // {uncovered - ok if there are no zeros}
nonZeroTotal++; nonZeroTotal++;
TEST_RESULT_INT_NE(nonZeroTotal, 0, "check that there are non-zero values in the buffer"); TEST_RESULT_INT_NE(nonZeroTotal, 0, "check that there are non-zero values in the buffer");
} }
FUNCTION_HARNESS_RESULT_VOID();
} }

Some files were not shown because too many files have changed in this diff Show More