mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Refactor common/archiveGet unit test.
The test was pretty old and written in stages during the migration, so storage use was a bit archaic and the organization was poor. Update using the new storage macros and reorganize the tests to provide better coverage.
This commit is contained in:
parent
8567b7f733
commit
f35d69c1c7
@ -565,7 +565,7 @@ unit:
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: archive-get
|
- name: archive-get
|
||||||
total: 5
|
total: 4
|
||||||
binReq: true
|
binReq: true
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
|
@ -11,6 +11,7 @@ Test Archive Get Command
|
|||||||
#include "storage/posix/storage.h"
|
#include "storage/posix/storage.h"
|
||||||
|
|
||||||
#include "common/harnessInfo.h"
|
#include "common/harnessInfo.h"
|
||||||
|
#include "common/harnessStorage.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Test Run
|
Test Run
|
||||||
@ -22,16 +23,6 @@ testRun(void)
|
|||||||
|
|
||||||
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
|
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
|
||||||
|
|
||||||
// Start a protocol server to test the protocol directly
|
|
||||||
Buffer *serverWrite = bufNew(8192);
|
|
||||||
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
|
|
||||||
ioWriteOpen(serverWriteIo);
|
|
||||||
|
|
||||||
ProtocolServer *server = protocolServerNew(
|
|
||||||
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
|
|
||||||
|
|
||||||
bufUsedSet(serverWrite, 0);
|
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("archiveGetCheck()"))
|
if (testBegin("archiveGetCheck()"))
|
||||||
{
|
{
|
||||||
@ -39,12 +30,12 @@ testRun(void)
|
|||||||
StringList *argList = strLstNew();
|
StringList *argList = strLstNew();
|
||||||
strLstAddZ(argList, "--stanza=test1");
|
strLstAddZ(argList, "--stanza=test1");
|
||||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
||||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath()));
|
strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
||||||
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
||||||
|
|
||||||
// Create pg_control file
|
// Create pg_control file
|
||||||
storagePutP(
|
storagePutP(
|
||||||
storageNewWriteP(storageTest, strNew("db/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
|
storageNewWriteP(storageTest, strNew("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
|
||||||
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
||||||
|
|
||||||
// Control and archive info mismatch
|
// Control and archive info mismatch
|
||||||
@ -117,132 +108,6 @@ testRun(void)
|
|||||||
"history file found");
|
"history file found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
|
||||||
if (testBegin("archiveGetFile()"))
|
|
||||||
{
|
|
||||||
// Load Parameters
|
|
||||||
StringList *argList = strLstNew();
|
|
||||||
strLstAddZ(argList, "--stanza=test1");
|
|
||||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
||||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath()));
|
|
||||||
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
|
||||||
|
|
||||||
// Create pg_control file
|
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(storageTest, strNew("db/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
|
|
||||||
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
|
||||||
|
|
||||||
// Create archive.info
|
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(storageTest, strNew("repo/archive/test1/archive.info")),
|
|
||||||
harnessInfoChecksumZ(
|
|
||||||
"[db]\n"
|
|
||||||
"db-id=1\n"
|
|
||||||
"\n"
|
|
||||||
"[db:history]\n"
|
|
||||||
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}"));
|
|
||||||
|
|
||||||
// Nothing to copy
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
String *archiveFile = strNew("01ABCDEF01ABCDEF01ABCDEF");
|
|
||||||
String *walDestination = strNewFmt("%s/db/pg_wal/RECOVERYXLOG", testPath());
|
|
||||||
storagePathCreateP(storageTest, strPath(walDestination));
|
|
||||||
|
|
||||||
TEST_RESULT_INT(
|
|
||||||
archiveGetFile(storageTest, archiveFile, walDestination, false, cipherTypeNone, NULL), 1, "WAL segment missing");
|
|
||||||
|
|
||||||
// Create a WAL segment to copy
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
Buffer *buffer = bufNew(16 * 1024 * 1024);
|
|
||||||
memset(bufPtr(buffer), 0, bufSize(buffer));
|
|
||||||
bufUsedSet(buffer, bufSize(buffer));
|
|
||||||
|
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(
|
|
||||||
storageTest,
|
|
||||||
strNew(
|
|
||||||
"repo/archive/test1/10-1/01ABCDEF01ABCDEF/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
|
|
||||||
buffer);
|
|
||||||
|
|
||||||
TEST_RESULT_INT(
|
|
||||||
archiveGetFile(storageTest, archiveFile, walDestination, false, cipherTypeNone, NULL), 0, "WAL segment copied");
|
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, walDestination), true, " check exists");
|
|
||||||
TEST_RESULT_UINT(storageInfoP(storageTest, walDestination).size, 16 * 1024 * 1024, " check size");
|
|
||||||
|
|
||||||
storageRemoveP(
|
|
||||||
storageTest,
|
|
||||||
strNew("repo/archive/test1/10-1/01ABCDEF01ABCDEF/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
|
|
||||||
.errorOnMissing = true);
|
|
||||||
storageRemoveP(storageTest, walDestination, .errorOnMissing = true);
|
|
||||||
|
|
||||||
// Create a compressed WAL segment to copy
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
StorageWrite *infoWrite = storageNewWriteP(storageTest, strNew("repo/archive/test1/archive.info"));
|
|
||||||
|
|
||||||
ioFilterGroupAdd(
|
|
||||||
ioWriteFilterGroup(storageWriteIo(infoWrite)), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc,
|
|
||||||
BUFSTRDEF("12345678"), NULL));
|
|
||||||
|
|
||||||
storagePutP(
|
|
||||||
infoWrite,
|
|
||||||
harnessInfoChecksumZ(
|
|
||||||
"[cipher]\n"
|
|
||||||
"cipher-pass=\"worstpassphraseever\"\n"
|
|
||||||
"\n"
|
|
||||||
"[db]\n"
|
|
||||||
"db-id=1\n"
|
|
||||||
"\n"
|
|
||||||
"[db:history]\n"
|
|
||||||
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}"));
|
|
||||||
|
|
||||||
StorageWrite *destination = storageNewWriteP(
|
|
||||||
storageTest,
|
|
||||||
strNew(
|
|
||||||
"repo/archive/test1/10-1/01ABCDEF01ABCDEF/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"));
|
|
||||||
|
|
||||||
IoFilterGroup *filterGroup = ioWriteFilterGroup(storageWriteIo(destination));
|
|
||||||
ioFilterGroupAdd(filterGroup, compressFilter(compressTypeGz, 3));
|
|
||||||
ioFilterGroupAdd(
|
|
||||||
filterGroup, cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, BUFSTRDEF("worstpassphraseever"), NULL));
|
|
||||||
storagePutP(destination, buffer);
|
|
||||||
|
|
||||||
TEST_RESULT_INT(
|
|
||||||
archiveGetFile(
|
|
||||||
storageTest, archiveFile, walDestination, false, cipherTypeAes256Cbc, strNew("12345678")), 0, "WAL segment copied");
|
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, walDestination), true, " check exists");
|
|
||||||
TEST_RESULT_UINT(storageInfoP(storageTest, walDestination).size, 16 * 1024 * 1024, " check size");
|
|
||||||
|
|
||||||
// Check protocol function directly
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
argList = strLstNew();
|
|
||||||
strLstAddZ(argList, "--stanza=test1");
|
|
||||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
||||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath()));
|
|
||||||
strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath()));
|
|
||||||
strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
|
|
||||||
strLstAddZ(argList, "--repo1-cipher-type=aes-256-cbc");
|
|
||||||
setenv("PGBACKREST_REPO1_CIPHER_PASS", "12345678", true);
|
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
|
||||||
unsetenv("PGBACKREST_REPO1_CIPHER_PASS");
|
|
||||||
|
|
||||||
storagePathCreateP(storageTest, strNew("spool/archive/test1/in"));
|
|
||||||
|
|
||||||
VariantList *paramList = varLstNew();
|
|
||||||
varLstAdd(paramList, varNewStr(archiveFile));
|
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
archiveGetProtocol(PROTOCOL_COMMAND_ARCHIVE_GET_STR, paramList, server), true, "protocol archive get");
|
|
||||||
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":0}\n", "check result");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageTest, strNewFmt("spool/archive/test1/in/%s", strZ(archiveFile))), true, " check exists");
|
|
||||||
|
|
||||||
bufUsedSet(serverWrite, 0);
|
|
||||||
|
|
||||||
// Check invalid protocol function
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
TEST_RESULT_BOOL(archiveGetProtocol(strNew(BOGUS_STR), paramList, server), false, "invalid function");
|
|
||||||
}
|
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("queueNeed()"))
|
if (testBegin("queueNeed()"))
|
||||||
{
|
{
|
||||||
@ -303,124 +168,120 @@ testRun(void)
|
|||||||
TEST_STORAGE_LIST(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000A00000FFE\n000000010000000A00000FFF\n");
|
TEST_STORAGE_LIST(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000A00000FFE\n000000010000000A00000FFF\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("cmdArchiveGetAsync()"))
|
if (testBegin("cmdArchiveGetAsync()"))
|
||||||
{
|
{
|
||||||
harnessLogLevelSet(logLevelDetail);
|
harnessLogLevelSet(logLevelDetail);
|
||||||
|
|
||||||
StringList *argCleanList = strLstNew();
|
// Arguments that must be included
|
||||||
strLstAdd(argCleanList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
StringList *argBaseList = strLstNew();
|
||||||
strLstAdd(argCleanList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
hrnCfgArgRawZ(argBaseList, cfgOptPgPath, TEST_PATH_PG);
|
||||||
strLstAdd(argCleanList, strNewFmt("--spool-path=%s/spool", testPath()));
|
hrnCfgArgRawZ(argBaseList, cfgOptRepoPath, TEST_PATH_REPO);
|
||||||
strLstAddZ(argCleanList, "--" CFGOPT_ARCHIVE_ASYNC);
|
hrnCfgArgRawZ(argBaseList, cfgOptSpoolPath, TEST_PATH_SPOOL);
|
||||||
strLstAddZ(argCleanList, "--stanza=test2");
|
hrnCfgArgRawBool(argBaseList, cfgOptArchiveAsync, true);
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argCleanList);
|
hrnCfgArgRawZ(argBaseList, cfgOptStanza, "test2");
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGetAsync(), ParamInvalidError, "at least one wal segment is required");
|
|
||||||
|
|
||||||
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "global.error\n", .remove = true);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("command must be run on the pg host");
|
TEST_TITLE("command must be run on the pg host");
|
||||||
|
|
||||||
StringList *argList = strLstNew();
|
StringList *argList = strLstDup(argBaseList);
|
||||||
hrnCfgArgRawZ(argList, cfgOptPgHost, "host");
|
hrnCfgArgRawZ(argList, cfgOptPgHost, BOGUS_STR);
|
||||||
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg");
|
|
||||||
hrnCfgArgRawZ(argList, cfgOptRepoPath, "/repo");
|
|
||||||
hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
|
|
||||||
strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
|
|
||||||
strLstAddZ(argList, "--" CFGOPT_STANZA "=test2");
|
|
||||||
strLstAddZ(argList, "000000010000000100000001");
|
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGetAsync(), HostInvalidError, "archive-get command must be run on the PostgreSQL host");
|
TEST_ERROR(cmdArchiveGetAsync(), HostInvalidError, "archive-get command must be run on the PostgreSQL host");
|
||||||
|
|
||||||
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "global.error\n", .remove = true);
|
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "global.error\n", .remove = true);
|
||||||
|
|
||||||
// Create pg_control file and archive.info
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storagePutP(
|
TEST_TITLE("error on no segments");
|
||||||
storageNewWriteP(storageTest, strNew("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
|
|
||||||
|
argList = strLstDup(argBaseList);
|
||||||
|
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
||||||
|
|
||||||
|
TEST_ERROR(cmdArchiveGetAsync(), ParamInvalidError, "at least one wal segment is required");
|
||||||
|
|
||||||
|
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "global.error\n", .remove = true);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("no segments to find");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT(
|
||||||
|
storagePgWrite(), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
|
||||||
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
||||||
|
|
||||||
storagePutP(
|
HRN_INFO_PUT(
|
||||||
storageNewWriteP(storageTest, strNew("repo/archive/test2/archive.info")),
|
storageRepoWrite(), INFO_ARCHIVE_PATH_FILE,
|
||||||
harnessInfoChecksumZ(
|
"[db]\n"
|
||||||
"[db]\n"
|
"db-id=1\n"
|
||||||
"db-id=1\n"
|
"\n"
|
||||||
"\n"
|
"[db:history]\n"
|
||||||
"[db:history]\n"
|
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}\n");
|
||||||
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}\n"));
|
|
||||||
|
|
||||||
// Get a single segment
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
argList = strLstDup(argCleanList);
|
|
||||||
strLstAddZ(argList, "000000010000000100000001");
|
strLstAddZ(argList, "000000010000000100000001");
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
||||||
|
|
||||||
storagePathCreateP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
TEST_RESULT_VOID(cmdArchiveGetAsync(), "get async");
|
||||||
|
|
||||||
TEST_RESULT_VOID(
|
harnessLogResult(
|
||||||
storagePutP(
|
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000100000001\n"
|
||||||
storageNewWriteP(
|
"P01 DETAIL: unable to find 000000010000000100000001 in the archive");
|
||||||
storageTest,
|
|
||||||
strNew(
|
|
||||||
"repo/archive/test2/10-1/0000000100000001/"
|
|
||||||
"000000010000000100000001-abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd")),
|
|
||||||
NULL),
|
|
||||||
"normal WAL segment");
|
|
||||||
|
|
||||||
// Create tmp file to make it look like a prior async get failed partway through to ensure that retries work
|
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000100000001.ok\n", .remove = true);
|
||||||
TEST_RESULT_VOID(
|
|
||||||
storagePutP(
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storageNewWriteP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.pgbackrest.tmp")),
|
TEST_TITLE("error on invalid compressed segment");
|
||||||
NULL),
|
|
||||||
"normal WAL segment");
|
HRN_STORAGE_PUT_EMPTY(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/000000010000000100000001-abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd.gz");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(cmdArchiveGetAsync(), "get async");
|
||||||
|
|
||||||
|
harnessLogResult(
|
||||||
|
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000100000001\n"
|
||||||
|
"P01 WARN: could not get 000000010000000100000001 from the archive (will be retried):"
|
||||||
|
" [29] raised from local-1 protocol: unexpected eof in compressed data");
|
||||||
|
|
||||||
|
TEST_STORAGE_LIST(
|
||||||
|
storageSpool(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000100000001.error\n000000010000000100000001.pgbackrest.tmp\n");
|
||||||
|
TEST_STORAGE_REMOVE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.error");
|
||||||
|
|
||||||
|
TEST_STORAGE_REMOVE(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/000000010000000100000001-abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd.gz");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("single segment");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_EMPTY(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/000000010000000100000001-abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
|
||||||
|
|
||||||
|
// There should be a temp file left over. Make sure it still exists to test that temp files are removed on retry.
|
||||||
|
TEST_STORAGE_EXISTS(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.pgbackrest.tmp");
|
||||||
|
|
||||||
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
|
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
|
||||||
|
|
||||||
harnessLogResult(
|
harnessLogResult(
|
||||||
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000100000001\n"
|
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000100000001\n"
|
||||||
"P01 DETAIL: found 000000010000000100000001 in the archive");
|
"P01 DETAIL: found 000000010000000100000001 in the archive");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000100000001\n", .remove = true);
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001")), true,
|
|
||||||
"check 000000010000000100000001 in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.pgbackrest.tmp")), false,
|
|
||||||
"check 000000010000000100000001 tmp not in spool");
|
|
||||||
|
|
||||||
// Get multiple segments where some are missing or errored
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
argList = strLstDup(argCleanList);
|
TEST_TITLE("multiple segments where some are missing or errored");
|
||||||
|
|
||||||
|
argList = strLstDup(argBaseList);
|
||||||
strLstAddZ(argList, "000000010000000100000001");
|
strLstAddZ(argList, "000000010000000100000001");
|
||||||
strLstAddZ(argList, "000000010000000100000002");
|
strLstAddZ(argList, "000000010000000100000002");
|
||||||
strLstAddZ(argList, "000000010000000100000003");
|
strLstAddZ(argList, "000000010000000100000003");
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleAsync, argList);
|
||||||
|
|
||||||
storagePathCreateP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
|
// Create segment duplicates
|
||||||
|
HRN_STORAGE_PUT_EMPTY(
|
||||||
TEST_RESULT_VOID(
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/000000010000000100000003-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||||
storagePutP(
|
HRN_STORAGE_PUT_EMPTY(
|
||||||
storageNewWriteP(
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/000000010000000100000003-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
|
||||||
storageTest,
|
|
||||||
strNew(
|
|
||||||
"repo/archive/test2/10-1/0000000100000001/"
|
|
||||||
"000000010000000100000003-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
|
|
||||||
NULL),
|
|
||||||
"normal WAL segment");
|
|
||||||
|
|
||||||
TEST_RESULT_VOID(
|
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(
|
|
||||||
storageTest,
|
|
||||||
strNew(
|
|
||||||
"repo/archive/test2/10-1/0000000100000001/"
|
|
||||||
"000000010000000100000003-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")),
|
|
||||||
NULL),
|
|
||||||
"duplicate WAL segment");
|
|
||||||
|
|
||||||
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
|
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
|
||||||
|
|
||||||
harnessLogResult(
|
harnessLogResult(
|
||||||
"P00 INFO: get 3 WAL file(s) from archive: 000000010000000100000001...000000010000000100000003\n"
|
"P00 INFO: get 3 WAL file(s) from archive: 000000010000000100000001...000000010000000100000003\n"
|
||||||
"P01 DETAIL: found 000000010000000100000001 in the archive\n"
|
"P01 DETAIL: found 000000010000000100000001 in the archive\n"
|
||||||
@ -431,35 +292,21 @@ testRun(void)
|
|||||||
"000000010000000100000003-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
|
"000000010000000100000003-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
|
||||||
" HINT: are multiple primaries archiving to this stanza?");
|
" HINT: are multiple primaries archiving to this stanza?");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
TEST_STORAGE_LIST(
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001")), true,
|
storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN,
|
||||||
"check 000000010000000100000001 in spool");
|
"000000010000000100000001\n000000010000000100000002.ok\n000000010000000100000003.error\n",
|
||||||
TEST_RESULT_BOOL(
|
.remove = true);
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000002")), false,
|
|
||||||
"check 000000010000000100000002 not in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000002.ok")), true,
|
|
||||||
"check 000000010000000100000002.ok in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000003")), false,
|
|
||||||
"check 000000010000000100000003 not in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000003.error")), true,
|
|
||||||
"check 000000010000000100000003.error in spool");
|
|
||||||
|
|
||||||
protocolFree();
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storageRemoveP(
|
TEST_TITLE("global error on invalid executable");
|
||||||
storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000003.error"), .errorOnMissing = true);
|
|
||||||
|
|
||||||
argList = strLstNew();
|
argList = strLstNew();
|
||||||
strLstAddZ(argList, "pgbackrest-bogus");
|
strLstAddZ(argList, "pgbackrest-bogus");
|
||||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH_PG);
|
||||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH_REPO);
|
||||||
strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath()));
|
hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH_SPOOL);
|
||||||
strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
|
hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
|
||||||
strLstAddZ(argList, "--stanza=test2");
|
hrnCfgArgRawZ(argList, cfgOptStanza, "test2");
|
||||||
strLstAddZ(argList, CFGCMD_ARCHIVE_GET ":" CONFIG_COMMAND_ROLE_ASYNC);
|
strLstAddZ(argList, CFGCMD_ARCHIVE_GET ":" CONFIG_COMMAND_ROLE_ASYNC);
|
||||||
strLstAddZ(argList, "000000010000000100000001");
|
strLstAddZ(argList, "000000010000000100000001");
|
||||||
strLstAddZ(argList, "000000010000000100000002");
|
strLstAddZ(argList, "000000010000000100000002");
|
||||||
@ -473,71 +320,60 @@ testRun(void)
|
|||||||
harnessLogResult(
|
harnessLogResult(
|
||||||
"P00 INFO: get 3 WAL file(s) from archive: 000000010000000100000001...000000010000000100000003");
|
"P00 INFO: get 3 WAL file(s) from archive: 000000010000000100000001...000000010000000100000003");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.error")), false,
|
|
||||||
"check 000000010000000100000001.error not in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000002.error")), false,
|
|
||||||
"check 000000010000000100000002.error not in spool");
|
|
||||||
TEST_RESULT_BOOL(
|
|
||||||
storageExistsP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000003.error")), false,
|
|
||||||
"check 000000010000000100000003.error not in spool");
|
|
||||||
TEST_RESULT_STR_Z(
|
TEST_RESULT_STR_Z(
|
||||||
strNewBuf(storageGetP(storageNewReadP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/global.error")))),
|
strNewBuf(storageGetP(storageNewReadP(storageSpool(), strNew(STORAGE_SPOOL_ARCHIVE_IN "/global.error")))),
|
||||||
"102\nlocal-1 process terminated unexpectedly [102]: unable to execute 'pgbackrest-bogus': "
|
"102\nlocal-1 process terminated unexpectedly [102]: unable to execute 'pgbackrest-bogus': "
|
||||||
"[2] No such file or directory",
|
"[2] No such file or directory",
|
||||||
"check global error");
|
"check global error");
|
||||||
|
|
||||||
|
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "global.error\n", .remove = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("cmdArchiveGet()"))
|
if (testBegin("cmdArchiveGet()"))
|
||||||
{
|
{
|
||||||
|
harnessLogLevelSet(logLevelDetail);
|
||||||
|
|
||||||
|
// Arguments that must be included. Use raw config here because we need to keep the
|
||||||
|
StringList *argBaseList = strLstNew();
|
||||||
|
strLstAddZ(argBaseList, "pgbackrest-bogus");
|
||||||
|
hrnCfgArgRawZ(argBaseList, cfgOptPgPath, TEST_PATH_PG);
|
||||||
|
hrnCfgArgRawZ(argBaseList, cfgOptRepoPath, TEST_PATH_REPO);
|
||||||
|
hrnCfgArgRawZ(argBaseList, cfgOptStanza, "test1");
|
||||||
|
hrnCfgArgRawZ(argBaseList, cfgOptArchiveTimeout, "1");
|
||||||
|
strLstAddZ(argBaseList, CFGCMD_ARCHIVE_GET);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("command must be run on the pg host");
|
TEST_TITLE("command must be run on the pg host");
|
||||||
|
|
||||||
StringList *argList = strLstNew();
|
StringList *argList = strLstDup(argBaseList);
|
||||||
hrnCfgArgRawZ(argList, cfgOptPgHost, "host");
|
hrnCfgArgRawZ(argList, cfgOptPgHost, BOGUS_STR);
|
||||||
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg");
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
hrnCfgArgRawZ(argList, cfgOptRepoPath, "/repo");
|
|
||||||
strLstAddZ(argList, "--" CFGOPT_STANZA "=test2");
|
|
||||||
strLstAddZ(argList, "000000010000000100000001");
|
|
||||||
strLstAddZ(argList, "pg_wal/000000010000000100000001");
|
|
||||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleDefault, argList);
|
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGet(), HostInvalidError, "archive-get command must be run on the PostgreSQL host");
|
TEST_ERROR(cmdArchiveGet(), HostInvalidError, "archive-get command must be run on the PostgreSQL host");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
argList = strLstNew();
|
argList = strLstDup(argBaseList);
|
||||||
strLstAddZ(argList, "pgbackrest-bogus"); // Break this until async tests are setup correctly
|
|
||||||
strLstAddZ(argList, "--archive-timeout=1");
|
|
||||||
strLstAdd(argList, strNewFmt("--lock-path=%s/lock", testPath()));
|
|
||||||
strLstAdd(argList, strNewFmt("--log-path=%s", testPath()));
|
|
||||||
strLstAdd(argList, strNewFmt("--log-level-file=debug"));
|
|
||||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
||||||
hrnCfgArgRawFmt(argList, cfgOptPgPath, "%s/db", testPath());
|
|
||||||
strLstAddZ(argList, "--stanza=test1");
|
|
||||||
strLstAddZ(argList, "archive-get");
|
|
||||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "WAL segment to get required");
|
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "WAL segment to get required");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
StringList *argListTemp = strLstDup(argList);
|
argList = strLstDup(argBaseList);
|
||||||
String *walSegment = strNew("000000010000000100000001");
|
strLstAddZ(argList, "000000010000000100000001");
|
||||||
strLstAdd(argListTemp, walSegment);
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp));
|
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "path to copy WAL segment required");
|
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "path to copy WAL segment required");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storagePutP(
|
HRN_STORAGE_PUT(
|
||||||
storageNewWriteP(storageTest, strNew("db/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
|
storagePgWrite(), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
|
||||||
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
||||||
|
|
||||||
storagePathCreateP(storageTest, strNewFmt("%s/db/pg_wal", testPath()));
|
storagePathCreateP(storageTest, strNewFmt("%s/pg/pg_wal", testPath()));
|
||||||
|
|
||||||
String *walFile = strNewFmt("%s/db/pg_wal/RECOVERYXLOG", testPath());
|
strLstAddZ(argList, TEST_PATH_PG "/pg_wal/RECOVERYXLOG");
|
||||||
strLstAdd(argListTemp, walFile);
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp));
|
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
cmdArchiveGet(), FileMissingError,
|
cmdArchiveGet(), FileMissingError,
|
||||||
@ -554,11 +390,12 @@ testRun(void)
|
|||||||
strZ(strNewFmt("%s/archive/test1/archive.info.copy", strZ(cfgOptionStr(cfgOptRepoPath)))));
|
strZ(strNewFmt("%s/archive/test1/archive.info.copy", strZ(cfgOptionStr(cfgOptRepoPath)))));
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
argListTemp = strLstDup(argList);
|
// !!! IS THIS TEST NEEDED
|
||||||
strLstAddZ(argListTemp, "00000001.history");
|
argList = strLstDup(argBaseList);
|
||||||
strLstAdd(argListTemp, walFile);
|
strLstAddZ(argList, "00000001.history");
|
||||||
strLstAddZ(argListTemp, "--archive-async");
|
strLstAddZ(argList, TEST_PATH_PG "/pg_wal/RECOVERYHISTORY");
|
||||||
harnessCfgLoadRaw(strLstSize(argListTemp), strLstPtr(argListTemp));
|
strLstAddZ(argList, "--archive-async");
|
||||||
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
cmdArchiveGet(), FileMissingError,
|
cmdArchiveGet(), FileMissingError,
|
||||||
@ -576,9 +413,10 @@ testRun(void)
|
|||||||
|
|
||||||
// Make sure the process times out when there is nothing to get
|
// Make sure the process times out when there is nothing to get
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
strLstAdd(argList, strNewFmt("--spool-path=%s/spool", testPath()));
|
argList = strLstDup(argBaseList);
|
||||||
strLstAddZ(argList, "--archive-async");
|
hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH_SPOOL);
|
||||||
strLstAdd(argList, walSegment);
|
hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
|
||||||
|
strLstAddZ(argList, "000000010000000100000001");
|
||||||
strLstAddZ(argList, "pg_wal/RECOVERYXLOG");
|
strLstAddZ(argList, "pg_wal/RECOVERYXLOG");
|
||||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
|
|
||||||
@ -590,51 +428,40 @@ testRun(void)
|
|||||||
|
|
||||||
// Check for missing WAL
|
// Check for missing WAL
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storagePutP(storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strZ(walSegment))), NULL);
|
HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok");
|
||||||
|
|
||||||
TEST_RESULT_INT(cmdArchiveGet(), 1, "successful get of missing WAL");
|
TEST_RESULT_INT(cmdArchiveGet(), 1, "successful get of missing WAL");
|
||||||
|
|
||||||
harnessLogResult("P00 INFO: unable to find 000000010000000100000001 in the archive");
|
harnessLogResult("P00 INFO: unable to find 000000010000000100000001 in the archive");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(
|
||||||
storageExistsP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s.ok", strZ(walSegment))), false,
|
storageExistsP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok")), false,
|
||||||
"check OK file was removed");
|
"check OK file was removed");
|
||||||
|
|
||||||
// Write out a WAL segment for success
|
// Write out a WAL segment for success
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
storagePutP(
|
HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001", "SHOULD-BE-A-REAL-WAL-FILE");
|
||||||
storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strZ(walSegment))),
|
|
||||||
BUFSTRDEF("SHOULD-BE-A-REAL-WAL-FILE"));
|
|
||||||
|
|
||||||
TEST_RESULT_INT(cmdArchiveGet(), 0, "successful get");
|
TEST_RESULT_INT(cmdArchiveGet(), 0, "successful get");
|
||||||
|
|
||||||
TEST_RESULT_VOID(harnessLogResult("P00 INFO: found 000000010000000100000001 in the archive"), "check log");
|
TEST_RESULT_VOID(harnessLogResult("P00 INFO: found 000000010000000100000001 in the archive"), "check log");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN);
|
||||||
storageExistsP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strZ(walSegment))), false,
|
TEST_STORAGE_LIST(storageTest, TEST_PATH_PG "/pg_wal", "RECOVERYXLOG\n", .remove = true);
|
||||||
"check WAL segment was removed from source");
|
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, walFile), true, "check WAL segment was moved to destination");
|
|
||||||
storageRemoveP(storageTest, walFile, .errorOnMissing = true);
|
|
||||||
|
|
||||||
// Write more WAL segments (in this case queue should be full)
|
// Write more WAL segments (in this case queue should be full)
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
strLstAddZ(argList, "--archive-get-queue-max=48");
|
strLstAddZ(argList, "--archive-get-queue-max=48");
|
||||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
|
|
||||||
String *walSegment2 = strNew("000000010000000100000002");
|
HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001", "SHOULD-BE-A-REAL-WAL-FILE");
|
||||||
|
HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000002", "SHOULD-BE-A-REAL-WAL-FILE");
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strZ(walSegment))),
|
|
||||||
BUFSTRDEF("SHOULD-BE-A-REAL-WAL-FILE"));
|
|
||||||
storagePutP(
|
|
||||||
storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strZ(walSegment2))),
|
|
||||||
BUFSTRDEF("SHOULD-BE-A-REAL-WAL-FILE"));
|
|
||||||
|
|
||||||
TEST_RESULT_INT(cmdArchiveGet(), 0, "successful get");
|
TEST_RESULT_INT(cmdArchiveGet(), 0, "successful get");
|
||||||
|
|
||||||
TEST_RESULT_VOID(harnessLogResult("P00 INFO: found 000000010000000100000001 in the archive"), "check log");
|
TEST_RESULT_VOID(harnessLogResult("P00 INFO: found 000000010000000100000001 in the archive"), "check log");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, walFile), true, "check WAL segment was moved");
|
TEST_STORAGE_LIST(storageTest, TEST_PATH_PG "/pg_wal", "RECOVERYXLOG\n", .remove = true);
|
||||||
|
|
||||||
// Make sure the process times out when it can't get a lock
|
// Make sure the process times out when it can't get a lock
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -653,6 +480,132 @@ testRun(void)
|
|||||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||||
|
|
||||||
TEST_ERROR(cmdArchiveGet(), ParamInvalidError, "extra parameters found");
|
TEST_ERROR(cmdArchiveGet(), ParamInvalidError, "extra parameters found");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("file is missing");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT(
|
||||||
|
storagePgWrite(), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
|
||||||
|
pgControlTestToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
|
||||||
|
|
||||||
|
HRN_INFO_PUT(
|
||||||
|
storageRepoWrite(), INFO_ARCHIVE_PATH_FILE,
|
||||||
|
"[db]\n"
|
||||||
|
"db-id=1\n"
|
||||||
|
"\n"
|
||||||
|
"[db:history]\n"
|
||||||
|
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH_PG);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH_REPO);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
|
||||||
|
strLstAddZ(argList, "01ABCDEF01ABCDEF01ABCDEF");
|
||||||
|
strLstAddZ(argList, TEST_PATH_PG "/pg_wal/RECOVERYXLOG");
|
||||||
|
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
||||||
|
|
||||||
|
TEST_RESULT_INT(cmdArchiveGet(), 1, "get");
|
||||||
|
|
||||||
|
harnessLogResult("P00 INFO: unable to find 01ABCDEF01ABCDEF01ABCDEF in the archive");
|
||||||
|
|
||||||
|
TEST_STORAGE_LIST_EMPTY(storageTest, TEST_PATH_PG "/pg_wal");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("get WAL segment");
|
||||||
|
|
||||||
|
Buffer *buffer = bufNew(16 * 1024 * 1024);
|
||||||
|
memset(bufPtr(buffer), 0, bufSize(buffer));
|
||||||
|
bufUsedSet(buffer, bufSize(buffer));
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
buffer);
|
||||||
|
|
||||||
|
TEST_RESULT_INT(cmdArchiveGet(), 0, "get");
|
||||||
|
|
||||||
|
harnessLogResult("P00 INFO: found 01ABCDEF01ABCDEF01ABCDEF in the archive");
|
||||||
|
|
||||||
|
TEST_RESULT_UINT(
|
||||||
|
storageInfoP(storageTest, STRDEF(TEST_PATH_PG "/pg_wal/RECOVERYXLOG")).size, 16 * 1024 * 1024, "check size");
|
||||||
|
TEST_STORAGE_LIST(storageTest, TEST_PATH_PG "/pg_wal", "RECOVERYXLOG\n", .remove = true);
|
||||||
|
|
||||||
|
TEST_STORAGE_REMOVE(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("get compressed and encrypted WAL segment");
|
||||||
|
|
||||||
|
HRN_INFO_PUT(
|
||||||
|
storageRepoWrite(), INFO_ARCHIVE_PATH_FILE,
|
||||||
|
"[cipher]\n"
|
||||||
|
"cipher-pass=\"" TEST_CIPHER_PASS_ARCHIVE "\"\n"
|
||||||
|
"\n"
|
||||||
|
"[db]\n"
|
||||||
|
"db-id=1\n"
|
||||||
|
"\n"
|
||||||
|
"[db:history]\n"
|
||||||
|
"1={\"db-id\":18072658121562454734,\"db-version\":\"10\"}",
|
||||||
|
.cipherType = cipherTypeAes256Cbc);
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT(
|
||||||
|
storageRepoWrite(), STORAGE_REPO_ARCHIVE "/10-1/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
buffer, .compressType = compressTypeGz, .cipherType = cipherTypeAes256Cbc, .cipherPass = TEST_CIPHER_PASS_ARCHIVE);
|
||||||
|
|
||||||
|
// Add encryption options
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoCipherType, CIPHER_TYPE_AES_256_CBC);
|
||||||
|
hrnCfgEnvRawZ(cfgOptRepoCipherPass, TEST_CIPHER_PASS);
|
||||||
|
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
||||||
|
hrnCfgEnvRemoveRaw(cfgOptRepoCipherPass);
|
||||||
|
|
||||||
|
TEST_RESULT_INT(cmdArchiveGet(), 0, "get");
|
||||||
|
|
||||||
|
harnessLogResult("P00 INFO: found 01ABCDEF01ABCDEF01ABCDEF in the archive");
|
||||||
|
|
||||||
|
TEST_STORAGE_LIST(storageTest, TEST_PATH_PG "/pg_wal", "RECOVERYXLOG\n");
|
||||||
|
TEST_RESULT_UINT(
|
||||||
|
storageInfoP(storageTest, STRDEF(TEST_PATH_PG "/pg_wal/RECOVERYXLOG")).size, 16 * 1024 * 1024, "check size");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("call protocol function directly");
|
||||||
|
|
||||||
|
// Start a protocol server
|
||||||
|
Buffer *serverWrite = bufNew(8192);
|
||||||
|
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
|
||||||
|
ioWriteOpen(serverWriteIo);
|
||||||
|
|
||||||
|
ProtocolServer *server = protocolServerNew(
|
||||||
|
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
|
||||||
|
|
||||||
|
bufUsedSet(serverWrite, 0);
|
||||||
|
|
||||||
|
// Add spool path
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH_PG);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH_REPO);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoCipherType, CIPHER_TYPE_AES_256_CBC);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH_SPOOL);
|
||||||
|
hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
|
||||||
|
hrnCfgEnvRawZ(cfgOptRepoCipherPass, TEST_CIPHER_PASS);
|
||||||
|
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleLocal, argList);
|
||||||
|
hrnCfgEnvRemoveRaw(cfgOptRepoCipherPass);
|
||||||
|
|
||||||
|
// Setup protocol command
|
||||||
|
VariantList *paramList = varLstNew();
|
||||||
|
varLstAdd(paramList, varNewStrZ("01ABCDEF01ABCDEF01ABCDEF"));
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(
|
||||||
|
archiveGetProtocol(PROTOCOL_COMMAND_ARCHIVE_GET_STR, paramList, server), true, "protocol archive get");
|
||||||
|
|
||||||
|
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":0}\n", "check result");
|
||||||
|
TEST_STORAGE_LIST(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000100000002\n01ABCDEF01ABCDEF01ABCDEF\n");
|
||||||
|
|
||||||
|
bufUsedSet(serverWrite, 0);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("invalid protocol command");
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(archiveGetProtocol(strNew(BOGUS_STR), paramList, server), false, "invalid function");
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNCTION_HARNESS_RESULT_VOID();
|
FUNCTION_HARNESS_RESULT_VOID();
|
||||||
|
Loading…
Reference in New Issue
Block a user