1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-01 00:25:06 +02:00
Files
pgbackrest/test/src/common/harnessInfo.c
David Steele ec173f12fb Add MEM_CONTEXT_PRIOR() block and update current call sites.
This macro block encapsulates the common pattern of switching to the prior (formerly called old) mem context to return results from a function.

Also rename MEM_CONTEXT_OLD() to memContextPrior().  This violates our convention of macros being in all caps but memContextPrior() will become a function very soon so this will reduce churn.
2020-01-17 13:29:49 -07:00

123 lines
4.6 KiB
C

/***********************************************************************************************************************************
Harness for Loading Test Configurations
***********************************************************************************************************************************/
#include <string.h>
#include "common/assert.h"
#include "common/crypto/hash.h"
#include "common/io/bufferRead.h"
#include "common/io/filter/filter.intern.h"
#include "common/type/json.h"
#include "info/info.h"
#include "version.h"
#include "common/harnessDebug.h"
#include "common/harnessInfo.h"
/***********************************************************************************************************************************
Add header and checksum to an info file
This prevents churn in headers and checksums in the unit tests. We purposefully do not use the checksum macros from the info module
here as a cross-check of that code.
***********************************************************************************************************************************/
typedef struct HarnessInfoChecksumData
{
MemContext *memContext; // Mem context to use for storing data in this structure
String *sectionLast; // The last section seen during load
IoFilter *checksum; // Checksum calculated from the file
} HarnessInfoChecksumData;
static void
harnessInfoChecksumCallback(void *callbackData, const String *section, const String *key, const String *value)
{
HarnessInfoChecksumData *data = (HarnessInfoChecksumData *)callbackData;
// Calculate checksum
if (data->sectionLast == NULL || !strEq(section, data->sectionLast))
{
if (data->sectionLast != NULL)
ioFilterProcessIn(data->checksum, BUFSTRDEF("},"));
ioFilterProcessIn(data->checksum, BUFSTRDEF("\""));
ioFilterProcessIn(data->checksum, BUFSTR(section));
ioFilterProcessIn(data->checksum, BUFSTRDEF("\":{"));
MEM_CONTEXT_BEGIN(data->memContext)
{
data->sectionLast = strDup(section);
}
MEM_CONTEXT_END();
}
else
ioFilterProcessIn(data->checksum, BUFSTRDEF(","));
ioFilterProcessIn(data->checksum, BUFSTR(jsonFromStr(key)));
ioFilterProcessIn(data->checksum, BUFSTRDEF(":"));
ioFilterProcessIn(data->checksum, BUFSTR(value));
}
Buffer *
harnessInfoChecksum(const String *info)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRING, info);
FUNCTION_HARNESS_END();
Buffer *result = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
// Initialize callback data
HarnessInfoChecksumData data =
{
.memContext = MEM_CONTEXT_TEMP(),
.checksum = cryptoHashNew(HASH_TYPE_SHA1_STR),
};
// Create buffer with space for data, header, and checksum
result = bufNew(strSize(info) + 256);
bufCat(result, BUFSTRDEF("[backrest]\nbackrest-format="));
bufCat(result, BUFSTR(jsonFromUInt(REPOSITORY_FORMAT)));
bufCat(result, BUFSTRDEF("\nbackrest-version="));
bufCat(result, BUFSTR(jsonFromStr(STRDEF(PROJECT_VERSION))));
bufCat(result, BUFSTRDEF("\n\n"));
bufCat(result, BUFSTR(info));
// Generate checksum by loading ini file
ioFilterProcessIn(data.checksum, BUFSTRDEF("{"));
iniLoad(ioBufferReadNew(result), harnessInfoChecksumCallback, &data);
ioFilterProcessIn(data.checksum, BUFSTRDEF("}}"));
// Append checksum to buffer
bufCat(result, BUFSTRDEF("\n[backrest]\nbackrest-checksum="));
bufCat(result, BUFSTR(jsonFromVar(ioFilterResult(data.checksum))));
bufCat(result, BUFSTRDEF("\n"));
bufMove(result, memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_HARNESS_RESULT(BUFFER, result);
}
Buffer *
harnessInfoChecksumZ(const char *info)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, info);
FUNCTION_HARNESS_END();
FUNCTION_HARNESS_RESULT(BUFFER, harnessInfoChecksum(STR(info)));
}
/***********************************************************************************************************************************
Test callback that logs the results to a string
***********************************************************************************************************************************/
void
harnessInfoLoadNewCallback(void *callbackData, const String *section, const String *key, const String *value)
{
if (callbackData != NULL)
strCatFmt((String *)callbackData, "[%s] %s=%s\n", strPtr(section), strPtr(key), strPtr(value));
}