mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Merge protocol storage helper into storage helper.
These are separated the same way in the Perl code where the remote storage driver is located in the Protocol module. However, in the C code the intention is to implement the remote storage driver as a regular driver in the storage layer rather than making a special case out of it. So, merge the storage helpers. This also has the benefit of making the code a bit simpler. Also separate storageSpool() and storageSpoolWrite() to make it clearer which operations require write access and to maintain consistency with the other storage helper functions.
This commit is contained in:
parent
3014b05dab
commit
84ab787b1a
@ -53,7 +53,7 @@
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Storage refactoring. Posix file functions now differentiate between open and missing errors. Don't use negations in objects below Storage. Rename posix driver files/functions for consistency. Full abstraction of storage driver interface.</p>
|
||||
<p>Storage refactoring. Posix file functions now differentiate between open and missing errors. Don't use negations in objects below Storage. Rename posix driver files/functions for consistency. Full abstraction of storage driver interface. Merge protocol storage helper into storage helper.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
|
12
src/Makefile
12
src/Makefile
@ -112,7 +112,6 @@ SRCS = \
|
||||
perl/exec.c \
|
||||
postgres/info.c \
|
||||
postgres/pageChecksum.c \
|
||||
protocol/storage/helper.c \
|
||||
storage/driver/posix/storage.c \
|
||||
storage/driver/posix/common.c \
|
||||
storage/driver/posix/fileRead.c \
|
||||
@ -142,13 +141,13 @@ install: pgbackrest
|
||||
####################################################################################################################################
|
||||
# Compile rules
|
||||
####################################################################################################################################
|
||||
command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h protocol/storage/helper.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
$(CC) $(CFLAGS) -c command/archive/common.c -o command/archive/common.o
|
||||
|
||||
command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h info/infoArchive.h info/infoPg.h postgres/info.h protocol/storage/helper.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h info/infoArchive.h info/infoPg.h postgres/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
$(CC) $(CFLAGS) -c command/archive/get/file.c -o command/archive/get/file.o
|
||||
|
||||
command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/archive/get/file.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/info.h protocol/storage/helper.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/archive/get/file.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
$(CC) $(CFLAGS) -c command/archive/get/get.c -o command/archive/get/get.o
|
||||
|
||||
command/archive/push/push.o: command/archive/push/push.c command/archive/common.h command/command.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
|
||||
@ -319,9 +318,6 @@ postgres/info.o: postgres/info.c common/debug.h common/error.auto.h common/error
|
||||
postgres/pageChecksum.o: postgres/pageChecksum.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h postgres/pageChecksum.h postgres/type.h
|
||||
$(CC) $(CFLAGS) -funroll-loops -ftree-vectorize -c postgres/pageChecksum.c -o postgres/pageChecksum.o
|
||||
|
||||
protocol/storage/helper.o: protocol/storage/helper.c common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h protocol/storage/helper.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
$(CC) $(CFLAGS) -c protocol/storage/helper.c -o protocol/storage/helper.o
|
||||
|
||||
storage/driver/posix/common.o: storage/driver/posix/common.c common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/common.h
|
||||
$(CC) $(CFLAGS) -c storage/driver/posix/common.c -o storage/driver/posix/common.o
|
||||
|
||||
@ -340,7 +336,7 @@ storage/fileRead.o: storage/fileRead.c common/assert.h common/debug.h common/err
|
||||
storage/fileWrite.o: storage/fileWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h storage/fileWrite.h storage/fileWrite.intern.h version.h
|
||||
$(CC) $(CFLAGS) -c storage/fileWrite.c -o storage/fileWrite.o
|
||||
|
||||
storage/helper.o: storage/helper.c common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
storage/helper.o: storage/helper.c common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
$(CC) $(CFLAGS) -c storage/helper.c -o storage/helper.o
|
||||
|
||||
storage/storage.o: storage/storage.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h
|
||||
|
@ -13,7 +13,7 @@ Archive Push Command
|
||||
#include "common/regExp.h"
|
||||
#include "common/wait.h"
|
||||
#include "postgres/version.h"
|
||||
#include "protocol/storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -12,7 +12,7 @@ Archive Get File
|
||||
#include "config/config.h"
|
||||
#include "info/infoArchive.h"
|
||||
#include "postgres/info.h"
|
||||
#include "protocol/storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -18,7 +18,7 @@ Archive Get Command
|
||||
#include "config/load.h"
|
||||
#include "perl/exec.h"
|
||||
#include "postgres/info.h"
|
||||
#include "protocol/storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -78,7 +78,7 @@ queueNeed(const String *walSegment, bool found, size_t queueSize, size_t walSegm
|
||||
|
||||
// Else delete it
|
||||
else
|
||||
storageRemoveNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(file)));
|
||||
storageRemoveNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(file)));
|
||||
}
|
||||
|
||||
// Generate a list of the WAL that are needed by removing kept WAL from the ideal queue
|
||||
@ -150,7 +150,8 @@ cmdArchiveGet(void)
|
||||
if (archiveAsyncStatus(archiveModeGet, walSegment, confessOnError))
|
||||
{
|
||||
storageRemoveP(
|
||||
storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strPtr(walSegment)), .errorOnMissing = true);
|
||||
storageSpoolWrite(),
|
||||
strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strPtr(walSegment)), .errorOnMissing = true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -176,7 +177,7 @@ cmdArchiveGet(void)
|
||||
.noAtomic = true);
|
||||
|
||||
// Move (or copy if required) the file
|
||||
storageMoveNP(storageSpool(), source, destination);
|
||||
storageMoveNP(storageSpoolWrite(), source, destination);
|
||||
|
||||
// Return success
|
||||
result = 0;
|
||||
@ -226,7 +227,7 @@ cmdArchiveGet(void)
|
||||
unsigned int walSegmentSize = WAL_SEGMENT_DEFAULT_SIZE;
|
||||
|
||||
// Create the queue
|
||||
storagePathCreateNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
||||
storagePathCreateNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
||||
|
||||
// Clean the current queue using the list of WAL that we ideally want in the queue. queueNeed()
|
||||
// will return the list of WAL needed to fill the queue and this will be passed to the async process.
|
||||
|
@ -1,106 +0,0 @@
|
||||
/***********************************************************************************************************************************
|
||||
Protocol Storage Helper
|
||||
***********************************************************************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/regExp.h"
|
||||
#include "config/config.h"
|
||||
#include "protocol/storage/helper.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/storage.intern.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Local variables
|
||||
***********************************************************************************************************************************/
|
||||
struct
|
||||
{
|
||||
MemContext *memContext; // Mem context for protocol storage
|
||||
Storage *storageRepo; // Repository read-only storage
|
||||
String *stanza; // Stanza for storage
|
||||
RegExp *walRegExp; // Regular expression for identifying wal files
|
||||
} protocolStorageHelper;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create the storage helper memory context
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
protocolStorageHelperInit(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (protocolStorageHelper.memContext == NULL)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(memContextTop())
|
||||
{
|
||||
protocolStorageHelper.memContext = memContextNew("protocolStorageHelper");
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a spool storage object
|
||||
***********************************************************************************************************************************/
|
||||
static String *
|
||||
storageRepoPathExpression(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;
|
||||
|
||||
if (strEqZ(expression, STORAGE_REPO_ARCHIVE))
|
||||
{
|
||||
result = strNewFmt("archive/%s", strPtr(protocolStorageHelper.stanza));
|
||||
|
||||
if (path != NULL)
|
||||
{
|
||||
StringList *pathSplit = strLstNewSplitZ(path, "/");
|
||||
String *file = strLstSize(pathSplit) == 2 ? strLstGet(pathSplit, 1) : NULL;
|
||||
|
||||
if (file != NULL && regExpMatch(protocolStorageHelper.walRegExp, file))
|
||||
strCatFmt(result, "/%s/%s/%s", strPtr(strLstGet(pathSplit, 0)), strPtr(strSubN(file, 0, 16)), strPtr(file));
|
||||
else
|
||||
strCatFmt(result, "/%s", strPtr(path));
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
|
||||
|
||||
FUNCTION_TEST_RESULT(STRING, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a read-only repository storage object
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *
|
||||
storageRepo(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (protocolStorageHelper.storageRepo == NULL)
|
||||
{
|
||||
protocolStorageHelperInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(protocolStorageHelper.memContext)
|
||||
{
|
||||
protocolStorageHelper.stanza = strDup(cfgOptionStr(cfgOptStanza));
|
||||
protocolStorageHelper.walRegExp = regExpNew(strNew("^[0-F]{24}"));
|
||||
protocolStorageHelper.storageRepo = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false,
|
||||
storageRepoPathExpression));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, protocolStorageHelper.storageRepo);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/***********************************************************************************************************************************
|
||||
Protocol Storage Helper
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef PROTOCOL_STORAGE_HELPER_H
|
||||
#define PROTOCOL_STORAGE_HELPER_H
|
||||
|
||||
#include "storage/storage.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Repo storage path constants
|
||||
***********************************************************************************************************************************/
|
||||
#define STORAGE_REPO_ARCHIVE "<REPO:ARCHIVE>"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Repository storage types
|
||||
***********************************************************************************************************************************/
|
||||
#define STORAGE_TYPE_CIFS "cifs"
|
||||
#define STORAGE_TYPE_POSIX "posix"
|
||||
#define STORAGE_TYPE_S3 "s3"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *storageRepo(void);
|
||||
|
||||
#endif
|
@ -5,26 +5,27 @@ Storage Helper
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/regExp.h"
|
||||
#include "config/config.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
#include "storage/helper.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Mem context for storage helper
|
||||
Local variables
|
||||
***********************************************************************************************************************************/
|
||||
static MemContext *memContextStorageHelper = NULL;
|
||||
static struct
|
||||
{
|
||||
MemContext *memContext; // Mem context for storage helper
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Cache for local storage
|
||||
***********************************************************************************************************************************/
|
||||
static Storage *storageLocalData = NULL;
|
||||
static Storage *storageLocalWriteData = NULL;
|
||||
Storage *storageLocal; // Local read-only storage
|
||||
Storage *storageLocalWrite; // Local write storage
|
||||
Storage *storageRepo; // Repository read-only storage
|
||||
Storage *storageSpool; // Spool read-only storage
|
||||
Storage *storageSpoolWrite; // Spool write storage
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Cache for spool storage
|
||||
***********************************************************************************************************************************/
|
||||
static Storage *storageSpoolData = NULL;
|
||||
static const String *storageSpoolStanza = NULL;
|
||||
String *stanza; // Stanza for storage
|
||||
RegExp *walRegExp; // Regular expression for identifying wal files
|
||||
} storageHelper;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create the storage helper memory context
|
||||
@ -34,11 +35,11 @@ storageHelperInit(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (memContextStorageHelper == NULL)
|
||||
if (storageHelper.memContext == NULL)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(memContextTop())
|
||||
{
|
||||
memContextStorageHelper = memContextNew("storageHelper");
|
||||
storageHelper.memContext = memContextNew("storageHelper");
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -46,6 +47,31 @@ storageHelperInit(void)
|
||||
FUNCTION_TEST_RESULT_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Initialize the stanza and error if it changes
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
storageHelperStanzaInit(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageHelper.stanza == NULL)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.stanza = strDup(cfgOptionStr(cfgOptStanza));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
else if (!strEq(storageHelper.stanza, cfgOptionStr(cfgOptStanza)))
|
||||
{
|
||||
THROW_FMT(
|
||||
AssertError, "stanza has changed from '%s' to '%s'", strPtr(storageHelper.stanza), strPtr(cfgOptionStr(cfgOptStanza)));
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT_VOID();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a local storage object
|
||||
***********************************************************************************************************************************/
|
||||
@ -54,20 +80,20 @@ storageLocal(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageLocalData == NULL)
|
||||
if (storageHelper.storageLocal == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(memContextStorageHelper)
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageLocalData = storageDriverPosixInterface(
|
||||
storageHelper.storageLocal = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
strNew("/"), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false, NULL));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageLocalData);
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageHelper.storageLocal);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -80,20 +106,84 @@ storageLocalWrite(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageLocalWriteData == NULL)
|
||||
if (storageHelper.storageLocalWrite == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(memContextStorageHelper)
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageLocalWriteData = storageDriverPosixInterface(
|
||||
storageHelper.storageLocalWrite = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
strNew("/"), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageLocalWriteData);
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageHelper.storageLocalWrite);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a spool storage object
|
||||
***********************************************************************************************************************************/
|
||||
static String *
|
||||
storageRepoPathExpression(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;
|
||||
|
||||
if (strEqZ(expression, STORAGE_REPO_ARCHIVE))
|
||||
{
|
||||
result = strNewFmt("archive/%s", strPtr(storageHelper.stanza));
|
||||
|
||||
if (path != NULL)
|
||||
{
|
||||
StringList *pathSplit = strLstNewSplitZ(path, "/");
|
||||
String *file = strLstSize(pathSplit) == 2 ? strLstGet(pathSplit, 1) : NULL;
|
||||
|
||||
if (file != NULL && regExpMatch(storageHelper.walRegExp, file))
|
||||
strCatFmt(result, "/%s/%s/%s", strPtr(strLstGet(pathSplit, 0)), strPtr(strSubN(file, 0, 16)), strPtr(file));
|
||||
else
|
||||
strCatFmt(result, "/%s", strPtr(path));
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
|
||||
|
||||
FUNCTION_TEST_RESULT(STRING, result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a read-only repository storage object
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *
|
||||
storageRepo(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageHelper.storageRepo == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
storageHelperStanzaInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.walRegExp = regExpNew(strNew("^[0-F]{24}"));
|
||||
|
||||
storageHelper.storageRepo = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptRepoPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false,
|
||||
storageRepoPathExpression));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageHelper.storageRepo);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -114,16 +204,16 @@ storageSpoolPathExpression(const String *expression, const String *path)
|
||||
if (strEqZ(expression, STORAGE_SPOOL_ARCHIVE_IN))
|
||||
{
|
||||
if (path == NULL)
|
||||
result = strNewFmt("archive/%s/in", strPtr(storageSpoolStanza));
|
||||
result = strNewFmt("archive/%s/in", strPtr(storageHelper.stanza));
|
||||
else
|
||||
result = strNewFmt("archive/%s/in/%s", strPtr(storageSpoolStanza), strPtr(path));
|
||||
result = strNewFmt("archive/%s/in/%s", strPtr(storageHelper.stanza), strPtr(path));
|
||||
}
|
||||
else if (strEqZ(expression, STORAGE_SPOOL_ARCHIVE_OUT))
|
||||
{
|
||||
if (path == NULL)
|
||||
result = strNewFmt("archive/%s/out", strPtr(storageSpoolStanza));
|
||||
result = strNewFmt("archive/%s/out", strPtr(storageHelper.stanza));
|
||||
else
|
||||
result = strNewFmt("archive/%s/out/%s", strPtr(storageSpoolStanza), strPtr(path));
|
||||
result = strNewFmt("archive/%s/out/%s", strPtr(storageHelper.stanza), strPtr(path));
|
||||
}
|
||||
else
|
||||
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
|
||||
@ -132,21 +222,47 @@ storageSpoolPathExpression(const String *expression, const String *path)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a spool storage object
|
||||
Get a read-only spool storage object
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *
|
||||
storageSpool(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageSpoolData == NULL)
|
||||
if (storageHelper.storageSpool == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
storageHelperStanzaInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(memContextStorageHelper)
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageSpoolStanza = strDup(cfgOptionStr(cfgOptStanza));
|
||||
storageSpoolData = storageDriverPosixInterface(
|
||||
storageHelper.storageSpool = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, false,
|
||||
storageSpoolPathExpression));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageHelper.storageSpool);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a writable spool storage object
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *
|
||||
storageSpoolWrite(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (storageHelper.storageSpoolWrite == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
storageHelperStanzaInit();
|
||||
|
||||
MEM_CONTEXT_BEGIN(storageHelper.memContext)
|
||||
{
|
||||
storageHelper.storageSpoolWrite = storageDriverPosixInterface(
|
||||
storageDriverPosixNew(
|
||||
cfgOptionStr(cfgOptSpoolPath), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true,
|
||||
storageSpoolPathExpression));
|
||||
@ -154,5 +270,5 @@ storageSpool(void)
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageSpoolData);
|
||||
FUNCTION_TEST_RESULT(STORAGE, storageHelper.storageSpoolWrite);
|
||||
}
|
||||
|
@ -7,17 +7,27 @@ Storage Helper
|
||||
#include "storage/storage.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Spool storage path constants
|
||||
Storage path constants
|
||||
***********************************************************************************************************************************/
|
||||
#define STORAGE_SPOOL_ARCHIVE_IN "<SPOOL:ARCHIVE:IN>"
|
||||
#define STORAGE_SPOOL_ARCHIVE_OUT "<SPOOL:ARCHIVE:OUT>"
|
||||
|
||||
#define STORAGE_REPO_ARCHIVE "<REPO:ARCHIVE>"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Repository storage types
|
||||
***********************************************************************************************************************************/
|
||||
#define STORAGE_TYPE_CIFS "cifs"
|
||||
#define STORAGE_TYPE_POSIX "posix"
|
||||
#define STORAGE_TYPE_S3 "s3"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
const Storage *storageLocal(void);
|
||||
const Storage *storageLocalWrite(void);
|
||||
|
||||
const Storage *storageRepo(void);
|
||||
const Storage *storageSpool(void);
|
||||
const Storage *storageSpoolWrite(void);
|
||||
|
||||
#endif
|
||||
|
@ -530,13 +530,6 @@ unit:
|
||||
coverage:
|
||||
Protocol/Base/Minion: partial
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: storage-helper
|
||||
total: 2
|
||||
|
||||
coverage:
|
||||
protocol/storage/helper: full
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: helper-perl
|
||||
total: 2
|
||||
|
@ -3,7 +3,7 @@ Test Archive Common
|
||||
***********************************************************************************************************************************/
|
||||
#include <unistd.h>
|
||||
|
||||
#include "protocol/storage/helper.h"
|
||||
#include "storage/helper.h"
|
||||
#include "storage/driver/posix/storage.h"
|
||||
|
||||
#include "common/harnessConfig.h"
|
||||
@ -47,34 +47,34 @@ testRun(void)
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewStr(strNew(BOGUS_STR)));
|
||||
TEST_ERROR(
|
||||
archiveAsyncStatus(archiveModePush, segment, false), FormatError,
|
||||
"000000010000000100000001.ok content must have at least two lines");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewStr(strNew(BOGUS_STR "\n")));
|
||||
TEST_ERROR(
|
||||
archiveAsyncStatus(archiveModePush, segment, false), FormatError, "000000010000000100000001.ok message must be > 0");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewStr(strNew(BOGUS_STR "\nmessage")));
|
||||
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(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), NULL);
|
||||
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewStr(strNew("0\nwarning")));
|
||||
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file with warning");
|
||||
harnessLogResult("P00 WARN: warning");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewStr(strNew("25\nerror")));
|
||||
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "error status renamed to ok");
|
||||
harnessLogResult(
|
||||
@ -82,7 +82,7 @@ testRun(void)
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))),
|
||||
bufNewStr(strNew("")));
|
||||
TEST_ERROR(
|
||||
archiveAsyncStatus(archiveModePush, segment, false), AssertError,
|
||||
@ -96,7 +96,7 @@ testRun(void)
|
||||
"status file '000000010000000100000001.error' has no content");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))),
|
||||
bufNewStr(strNew("25\nmessage")));
|
||||
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, true), AssertError, "message");
|
||||
|
||||
|
@ -213,7 +213,7 @@ testRun(void)
|
||||
{
|
||||
StringList *argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAddZ(argList, "--stanza=test1");
|
||||
strLstAddZ(argList, "--archive-async");
|
||||
strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath()));
|
||||
strLstAddZ(argList, "archive-get");
|
||||
@ -224,10 +224,10 @@ testRun(void)
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
queueNeed(strNew("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_92),
|
||||
PathOpenError, "unable to open path '%s/spool/archive/db/in' for read: [2] No such file or directory", testPath());
|
||||
PathOpenError, "unable to open path '%s/spool/archive/test1/in' for read: [2] No such file or directory", testPath());
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePathCreateNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
||||
storagePathCreateNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(queueNeed(strNew("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_92), "|")),
|
||||
@ -246,30 +246,30 @@ testRun(void)
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE")), walSegmentBuffer);
|
||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE")), walSegmentBuffer);
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF")), walSegmentBuffer);
|
||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF")), walSegmentBuffer);
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(queueNeed(strNew("0000000100000001000000FE"), false, queueSize, walSegmentSize, PG_VERSION_92), "|")),
|
||||
"000000010000000200000000|000000010000000200000001", "queue has wal < 9.3");
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(storageListNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN)), "|")),
|
||||
strPtr(strLstJoin(storageListNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN)), "|")),
|
||||
"0000000100000001000000FE", "check queue");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
walSegmentSize = 1024 * 1024;
|
||||
queueSize = walSegmentSize * 5;
|
||||
|
||||
storagePutNP(storageNewWriteNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/junk")), bufNewStr(strNew("JUNK")));
|
||||
storagePutNP(storageNewWriteNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/junk")), bufNewStr(strNew("JUNK")));
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFE")), walSegmentBuffer);
|
||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFE")), walSegmentBuffer);
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFF")), walSegmentBuffer);
|
||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000A00000FFF")), walSegmentBuffer);
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(queueNeed(strNew("000000010000000A00000FFD"), true, queueSize, walSegmentSize, PG_VERSION_11), "|")),
|
||||
@ -279,7 +279,7 @@ testRun(void)
|
||||
strPtr(strLstJoin(strLstSort(storageListNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN)), sortOrderAsc), "|")),
|
||||
"000000010000000A00000FFE|000000010000000A00000FFF", "check queue");
|
||||
|
||||
storagePathRemoveP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN), .recurse = true);
|
||||
storagePathRemoveP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN), .recurse = true);
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -378,7 +378,7 @@ testRun(void)
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strPtr(walSegment))), NULL);
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strPtr(walSegment))), NULL);
|
||||
|
||||
TEST_RESULT_VOID(cmdArchiveGet(), "successful get of missing WAL");
|
||||
harnessLogResult("P00 INFO: unable to find 000000010000000100000001 in the archive");
|
||||
@ -390,7 +390,7 @@ testRun(void)
|
||||
// Write out a WAL segment for success
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment))),
|
||||
bufNewStr(strNew("SHOULD-BE-A-REAL-WAL-FILE")));
|
||||
|
||||
TEST_RESULT_VOID(cmdArchiveGet(), "successful get");
|
||||
@ -407,10 +407,10 @@ testRun(void)
|
||||
String *walSegment2 = strNew("000000010000000100000002");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment))),
|
||||
bufNewStr(strNew("SHOULD-BE-A-REAL-WAL-FILE")));
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment2))),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment2))),
|
||||
bufNewStr(strNew("SHOULD-BE-A-REAL-WAL-FILE")));
|
||||
|
||||
TEST_RESULT_VOID(cmdArchiveGet(), "successful get");
|
||||
|
@ -60,7 +60,7 @@ testRun(void)
|
||||
storagePathRemoveNP(storageTest, strNewFmt("%s/db/archive_status", testPath()));
|
||||
|
||||
String *errorFile = storagePathNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error"));
|
||||
storagePutNP(storageNewWriteNP(storageSpool(), errorFile), bufNewStr(strNew("25\n" BOGUS_STR)));
|
||||
storagePutNP(storageNewWriteNP(storageSpoolWrite(), errorFile), bufNewStr(strNew("25\n" BOGUS_STR)));
|
||||
|
||||
TEST_ERROR(cmdArchivePush(), AssertError, BOGUS_STR);
|
||||
|
||||
@ -69,13 +69,14 @@ testRun(void)
|
||||
// Write out a valid ok file and test for success
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok")),
|
||||
storageNewWriteNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok")),
|
||||
bufNewStr(strNew("")));
|
||||
|
||||
TEST_RESULT_VOID(cmdArchivePush(), "successful push");
|
||||
harnessLogResult("P00 INFO: pushed WAL segment 000000010000000100000001 asynchronously");
|
||||
|
||||
storageRemoveP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok"), .errorOnMissing = true);
|
||||
storageRemoveP(
|
||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok"), .errorOnMissing = true);
|
||||
|
||||
// Make sure the process times out when there is nothing to archive and it can't get a lock. This test MUST go last since
|
||||
// the lock is lost and cannot be closed by the main process.
|
||||
|
@ -1,67 +0,0 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Protocol Storage Helper
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/harnessConfig.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
String *writeFile = strNewFmt("%s/writefile", testPath());
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("protocolStorageHelperInit()"))
|
||||
{
|
||||
TEST_RESULT_PTR(protocolStorageHelper.memContext, NULL, "mem context not created");
|
||||
TEST_RESULT_VOID(protocolStorageHelperInit(), "create mem context");
|
||||
TEST_RESULT_BOOL(protocolStorageHelper.memContext != NULL, true, "mem context created");
|
||||
TEST_RESULT_VOID(protocolStorageHelperInit(), "reinit does nothing");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageRepo()"))
|
||||
{
|
||||
const Storage *storage = NULL;
|
||||
|
||||
// Load configuration to set repo-path and stanza
|
||||
StringList *argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAdd(argList, strNewFmt("--repo-path=%s", testPath()));
|
||||
strLstAddZ(argList, "archive-get");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_PTR(protocolStorageHelper.storageRepo, NULL, "repo storage not cached");
|
||||
TEST_ASSIGN(storage, storageRepo(), "new storage");
|
||||
TEST_RESULT_PTR(protocolStorageHelper.storageRepo, storage, "repo storage cached");
|
||||
TEST_RESULT_PTR(storageRepo(), storage, "get cached storage");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(storagePathNP(storage, strNew("<BOGUS>/path")), AssertError, "invalid expression '<BOGUS>'");
|
||||
TEST_ERROR(storageNewWriteNP(storage, writeFile), AssertError, "function debug assertion 'this->write' failed");
|
||||
|
||||
TEST_RESULT_STR(strPtr(storagePathNP(storage, NULL)), testPath(), "check base path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE))), strPtr(strNewFmt("%s/archive/db", testPath())),
|
||||
"check archive path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/simple"))),
|
||||
strPtr(strNewFmt("%s/archive/db/simple", testPath())), "check simple path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/700000007000000070000000"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/7000000070000000/700000007000000070000000", testPath())), "check segment path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/00000008.history"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/00000008.history", testPath())), "check history path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/000000010000014C0000001A.00000028.backup"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/000000010000014C/000000010000014C0000001A.00000028.backup", testPath())),
|
||||
"check backup path");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Storage Helper
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/harnessConfig.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
@ -12,29 +13,24 @@ testRun(void)
|
||||
|
||||
String *writeFile = strNewFmt("%s/writefile", testPath());
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("storageLocal()"))
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageLocal() and storageLocalWrite()"))
|
||||
{
|
||||
const Storage *storage = NULL;
|
||||
|
||||
TEST_RESULT_PTR(storageLocalData, NULL, "local storage not cached");
|
||||
TEST_RESULT_PTR(storageHelper.storageLocal, NULL, "local storage not cached");
|
||||
TEST_ASSIGN(storage, storageLocal(), "new storage");
|
||||
TEST_RESULT_PTR(storageLocalData, storage, "local storage cached");
|
||||
TEST_RESULT_PTR(storageHelper.storageLocal, storage, "local storage cached");
|
||||
TEST_RESULT_PTR(storageLocal(), storage, "get cached storage");
|
||||
|
||||
TEST_RESULT_STR(strPtr(storagePathNP(storage, NULL)), "/", "check base path");
|
||||
|
||||
TEST_ERROR(storageNewWriteNP(storage, writeFile), AssertError, "function debug assertion 'this->write' failed");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("storageLocalWrite()"))
|
||||
{
|
||||
const Storage *storage = NULL;
|
||||
|
||||
TEST_RESULT_PTR(storageLocalWriteData, NULL, "local storage not cached");
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(storageHelper.storageLocalWrite, NULL, "local storage not cached");
|
||||
TEST_ASSIGN(storage, storageLocalWrite(), "new storage");
|
||||
TEST_RESULT_PTR(storageLocalWriteData, storage, "local storage cached");
|
||||
TEST_RESULT_PTR(storageHelper.storageLocalWrite, storage, "local storage cached");
|
||||
TEST_RESULT_PTR(storageLocalWrite(), storage, "get cached storage");
|
||||
|
||||
TEST_RESULT_STR(strPtr(storagePathNP(storage, NULL)), "/", "check base path");
|
||||
@ -42,22 +38,80 @@ testRun(void)
|
||||
TEST_RESULT_VOID(storageNewWriteNP(storage, writeFile), "writes are allowed");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("storageSpool()"))
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageRepo()"))
|
||||
{
|
||||
const Storage *storage = NULL;
|
||||
|
||||
// Initialize config
|
||||
cfgInit();
|
||||
cfgOptionSet(cfgOptSpoolPath, cfgSourceConfig, varNewStr(strNew(testPath())));
|
||||
cfgOptionSet(cfgOptBufferSize, cfgSourceConfig, varNewInt(65536));
|
||||
cfgOptionSet(cfgOptStanza, cfgSourceConfig, varNewStr(strNew("db")));
|
||||
// Load configuration to set repo-path and stanza
|
||||
StringList *argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAdd(argList, strNewFmt("--repo-path=%s", testPath()));
|
||||
strLstAddZ(argList, "archive-get");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_PTR(storageSpoolData, NULL, "storage not cached");
|
||||
TEST_RESULT_PTR(storageHelper.storageRepo, NULL, "repo storage not cached");
|
||||
TEST_ASSIGN(storage, storageRepo(), "new storage");
|
||||
TEST_RESULT_PTR(storageHelper.storageRepo, storage, "repo storage cached");
|
||||
TEST_RESULT_PTR(storageRepo(), storage, "get cached storage");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(storagePathNP(storage, strNew("<BOGUS>/path")), AssertError, "invalid expression '<BOGUS>'");
|
||||
TEST_ERROR(storageNewWriteNP(storage, writeFile), AssertError, "function debug assertion 'this->write' failed");
|
||||
|
||||
TEST_RESULT_STR(strPtr(storagePathNP(storage, NULL)), testPath(), "check base path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE))), strPtr(strNewFmt("%s/archive/db", testPath())),
|
||||
"check archive path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/simple"))),
|
||||
strPtr(strNewFmt("%s/archive/db/simple", testPath())), "check simple path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/700000007000000070000000"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/7000000070000000/700000007000000070000000", testPath())), "check segment path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/00000008.history"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/00000008.history", testPath())), "check history path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_REPO_ARCHIVE "/9.4-1/000000010000014C0000001A.00000028.backup"))),
|
||||
strPtr(strNewFmt("%s/archive/db/9.4-1/000000010000014C/000000010000014C0000001A.00000028.backup", testPath())),
|
||||
"check backup path");
|
||||
|
||||
// Change the stanza name and make sure helper fails
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storageHelper.storageRepo = NULL;
|
||||
|
||||
argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=other");
|
||||
strLstAdd(argList, strNewFmt("--repo-path=%s", testPath()));
|
||||
strLstAddZ(argList, "archive-get");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_ERROR(storageRepo(), AssertError, "stanza has changed from 'db' to 'other'");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageSpool() and storageSpoolWrite()"))
|
||||
{
|
||||
const Storage *storage = NULL;
|
||||
|
||||
// Load configuration to set spool-path and stanza
|
||||
StringList *argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAddZ(argList, "--archive-async");
|
||||
strLstAdd(argList, strNewFmt("--spool-path=%s", testPath()));
|
||||
strLstAddZ(argList, "archive-get");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_PTR(storageHelper.storageSpool, NULL, "storage not cached");
|
||||
TEST_ASSIGN(storage, storageSpool(), "new storage");
|
||||
TEST_RESULT_PTR(storageSpoolData, storage, "storage cached");
|
||||
TEST_RESULT_PTR(storageHelper.storageSpool, storage, "storage cached");
|
||||
TEST_RESULT_PTR(storageSpool(), storage, "get cached storage");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_STR(strPtr(storagePathNP(storage, NULL)), testPath(), "check base path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(storagePathNP(storage, strNew(STORAGE_SPOOL_ARCHIVE_OUT))), strPtr(strNewFmt("%s/archive/db/out", testPath())),
|
||||
@ -75,6 +129,14 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(storagePathNP(storage, strNew("<" BOGUS_STR ">")), AssertError, "invalid expression '<BOGUS>'");
|
||||
|
||||
TEST_ERROR(storageNewWriteNP(storage, writeFile), AssertError, "function debug assertion 'this->write' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(storageHelper.storageSpoolWrite, NULL, "storage not cached");
|
||||
TEST_ASSIGN(storage, storageSpoolWrite(), "new storage");
|
||||
TEST_RESULT_PTR(storageHelper.storageSpoolWrite, storage, "storage cached");
|
||||
TEST_RESULT_PTR(storageSpoolWrite(), storage, "get cached storage");
|
||||
|
||||
TEST_RESULT_VOID(storageNewWriteNP(storage, writeFile), "writes are allowed");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user