diff --git a/doc/xml/release.xml b/doc/xml/release.xml
index 13149ad88..6d877fd52 100644
--- a/doc/xml/release.xml
+++ b/doc/xml/release.xml
@@ -96,6 +96,9 @@
+
+
+
diff --git a/test/src/module/command/archiveCommonTest.c b/test/src/module/command/archiveCommonTest.c
index 535f1d88c..b306e772b 100644
--- a/test/src/module/command/archiveCommonTest.c
+++ b/test/src/module/command/archiveCommonTest.c
@@ -25,67 +25,61 @@ testRun(void)
if (testBegin("archiveAsyncErrorClear() and archiveAsyncStatus()"))
{
StringList *argList = strLstNew();
- strLstAddZ(argList, "--spool-path=" TEST_PATH);
- strLstAddZ(argList, "--archive-async");
- strLstAddZ(argList, "--archive-timeout=1");
- strLstAddZ(argList, "--stanza=db");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH);
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
+ hrnCfgArgRawZ(argList, cfgOptArchiveTimeout, "1");
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("archiveAsyncStatus() - directory and status file not present");
+
const String *segment = STRDEF("000000010000000100000001");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), false, "directory and status file not present");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModeGet, segment, false, true), false, "directory and status file not present");
// -------------------------------------------------------------------------------------------------------------------------
- mkdir(TEST_PATH "/archive", 0750);
- mkdir(TEST_PATH "/archive/db", 0750);
- mkdir(TEST_PATH "/archive/db/out", 0750);
+ TEST_TITLE("archiveAsyncStatus() - directories present and status file not present");
+
+ HRN_STORAGE_PATH_CREATE(storageTest, "archive/db/out", .mode = 0750);
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), false, "status file not present");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("clear archive file errors");
- const String *errorSegment = strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strZ(segment));
- const String *errorGlobal = STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/global.error");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/global.error");
- storagePutP(storageNewWriteP(storageSpoolWrite(), errorSegment), NULL);
- storagePutP(storageNewWriteP(storageSpoolWrite(), errorGlobal), NULL);
+ TEST_STORAGE_LIST(storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT, "000000010000000100000001.error\nglobal.error\n");
TEST_RESULT_VOID(archiveAsyncErrorClear(archiveModePush, segment), "clear error");
- TEST_RESULT_BOOL(storageExistsP(storageSpool(), errorSegment), false, " check segment error");
- TEST_RESULT_BOOL(storageExistsP(storageSpool(), errorGlobal), false, " check global error");
+ TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT, .comment = "segment and global error cleared");
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))),
- BUFSTRDEF(BOGUS_STR));
+ TEST_TITLE("check ok file");
+
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", BOGUS_STR);
TEST_ERROR(
archiveAsyncStatus(archiveModePush, segment, false, true), FormatError,
"000000010000000100000001.ok content must have at least two lines");
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))),
- BUFSTRDEF(BOGUS_STR "\n"));
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", BOGUS_STR "\n");
TEST_ERROR(
archiveAsyncStatus(archiveModePush, segment, false, true), FormatError,
"000000010000000100000001.ok message must be > 0");
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))),
- BUFSTRDEF(BOGUS_STR "\nmessage"));
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", BOGUS_STR "\nmessage");
TEST_ERROR(
archiveAsyncStatus(archiveModePush, segment, false, true),
FormatError, "unable to convert base 10 string 'BOGUS' to int");
- storagePutP(storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))), NULL);
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), true, "ok file");
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))),
- BUFSTRDEF("0\nwarning"));
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", "0\nwarning");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), true, "ok file with warning");
TEST_RESULT_LOG("P00 WARN: warning");
@@ -97,36 +91,31 @@ testRun(void)
TEST_RESULT_LOG("");
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment))),
- BUFSTRDEF("25\nerror"));
+ TEST_TITLE("error status renamed to ok");
+
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", "25\nerror");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), true, "error status renamed to ok");
TEST_RESULT_LOG(
"P00 WARN: WAL segment '000000010000000100000001' was not pushed due to error [25] and was manually skipped: error");
- TEST_RESULT_VOID(
- storageRemoveP(
- storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strZ(segment)), .errorOnMissing = true),
- "remove ok");
+ HRN_STORAGE_REMOVE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok", .errorOnMissing = true);
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strZ(segment))), bufNew(0));
+ TEST_TITLE("segment error file - AssertError");
+
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error");
TEST_ERROR(
archiveAsyncStatus(archiveModePush, segment, true, true), AssertError,
"status file '000000010000000100000001.error' has no content");
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strZ(segment))),
- BUFSTRDEF("25\nmessage"));
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error", "25\nmessage");
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, true, true), AssertError, "message");
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false, true), false, "suppress error");
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/global.error")),
- BUFSTRDEF("102\nexecute error"));
+ TEST_TITLE("global error file - ExecuteError");
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/global.error", "102\nexecute error");
TEST_ERROR(archiveAsyncStatus(archiveModePush, STRDEF("anyfile"), true, true), ExecuteError, "execute error");
}
@@ -134,49 +123,40 @@ testRun(void)
if (testBegin("archiveAsyncStatusErrorWrite() and archiveAsyncStatusOkWrite()"))
{
StringList *argList = strLstNew();
- strLstAddZ(argList, "--spool-path=" TEST_PATH);
- strLstAddZ(argList, "--stanza=db");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH);
hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg");
- strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .role = cfgCmdRoleAsync);
const String *walSegment = STRDEF("000000010000000100000001");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("archiveAsyncStatusErrorWrite()");
+
TEST_RESULT_VOID(
- archiveAsyncStatusErrorWrite(archiveModeGet, walSegment, 25, STRDEF("error message")), "write error");
- TEST_RESULT_STR_Z(
- strNewBuf(storageGetP(storageNewReadP(storageTest, STRDEF("archive/db/in/000000010000000100000001.error")))),
- "25\nerror message", "check error");
- TEST_RESULT_VOID(
- storageRemoveP(storageTest, STRDEF("archive/db/in/000000010000000100000001.error"), .errorOnMissing = true),
- "remove error");
+ archiveAsyncStatusErrorWrite(archiveModeGet, walSegment, 25, STRDEF("error message")), "write segment error");
+ TEST_STORAGE_GET(
+ storageTest, "archive/db/in/000000010000000100000001.error", "25\nerror message", .remove = true,
+ .comment = "check segment error and remove");
TEST_RESULT_VOID(
archiveAsyncStatusErrorWrite(archiveModeGet, NULL, 25, STRDEF("global error message")), "write global error");
- TEST_RESULT_STR_Z(
- strNewBuf(storageGetP(storageNewReadP(storageTest, STRDEF("archive/db/in/global.error")))),
- "25\nglobal error message", "check global error");
- TEST_RESULT_VOID(
- storageRemoveP(storageTest, STRDEF("archive/db/in/global.error"), .errorOnMissing = true),
- "remove global error");
+ TEST_STORAGE_GET(
+ storageTest, "archive/db/in/global.error", "25\nglobal error message", .remove = true,
+ .comment = "check global error and remove");
- TEST_RESULT_VOID(
- archiveAsyncStatusOkWrite(archiveModeGet, walSegment, NULL), "write ok file");
- TEST_RESULT_STR_Z(
- strNewBuf(storageGetP(storageNewReadP(storageTest, STRDEF("archive/db/in/000000010000000100000001.ok")))),
- "", "check ok");
- TEST_RESULT_VOID(
- storageRemoveP(storageTest, STRDEF("archive/db/in/000000010000000100000001.ok"), .errorOnMissing = true),
- "remove ok");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("archiveAsyncStatusOkWrite()");
- TEST_RESULT_VOID(
- archiveAsyncStatusOkWrite(archiveModeGet, walSegment, STRDEF("WARNING")), "write ok file with warning");
- TEST_RESULT_STR_Z(
- strNewBuf(storageGetP(storageNewReadP(storageTest, STRDEF("archive/db/in/000000010000000100000001.ok")))),
- "0\nWARNING", "check ok warning");
- TEST_RESULT_VOID(
- storageRemoveP(storageTest, STRDEF("archive/db/in/000000010000000100000001.ok"), .errorOnMissing = true),
- "remove ok");
+ TEST_RESULT_VOID(archiveAsyncStatusOkWrite(archiveModeGet, walSegment, NULL), "write ok file");
+ TEST_STORAGE_GET(
+ storageTest, "archive/db/in/000000010000000100000001.ok", "", .remove = true, .comment = "check ok and remove");
+
+ TEST_RESULT_VOID(archiveAsyncStatusOkWrite(archiveModeGet, walSegment, STRDEF("WARNING")), "write ok file with warning");
+ TEST_STORAGE_GET(
+ storageTest, "archive/db/in/000000010000000100000001.ok", "0\nWARNING", .remove = true,
+ .comment = "check ok warning and remove");
}
// *****************************************************************************************************************************
@@ -197,8 +177,16 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("walPath()"))
{
+ StringList *argList = strLstNew();
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
+ hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg");
+ HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("absolute and relative paths");
+
const String *pgPath = storagePathP(storageTest, STRDEF("pg"));
- storagePathCreateP(storageTest, pgPath);
+ HRN_STORAGE_PATH_CREATE(storageTest, strZ(pgPath));
TEST_RESULT_STR_Z(walPath(STRDEF("/absolute/path"), pgPath, STRDEF("test")), "/absolute/path", "absolute path");
@@ -206,6 +194,9 @@ testRun(void)
TEST_RESULT_STR(
walPath(STRDEF("relative/path"), pgPath, STRDEF("test")), strNewFmt("%s/relative/path", strZ(pgPath)), "relative path");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("symlink path");
+
const String *pgPathLink = storagePathP(storageTest, STRDEF("pg-link"));
THROW_ON_SYS_ERROR_FMT(
symlink(strZ(pgPath), strZ(pgPathLink)) == -1, FileOpenError, "unable to create symlink '%s' to '%s'", strZ(pgPath),
@@ -216,6 +207,9 @@ testRun(void)
walPath(STRDEF("relative/path"), pgPathLink, STRDEF("test")), strNewFmt("%s/relative/path", strZ(pgPathLink)),
"relative path");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("path errors");
+
THROW_ON_SYS_ERROR(chdir("/") != 0, PathMissingError, "unable to chdir()");
TEST_ERROR(
walPath(STRDEF("relative/path"), pgPathLink, STRDEF("test")), OptionInvalidValueError,
@@ -234,15 +228,17 @@ testRun(void)
{
// Load configuration to set repo-path and stanza
StringList *argList = strLstNew();
- strLstAddZ(argList, "--stanza=db");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/pg");
- strLstAddZ(argList, "--repo-path=" TEST_PATH);
- strLstAddZ(argList, "archive-get");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH);
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("no path or segment");
+
TEST_RESULT_STR(walSegmentFind(storageRepo(), STRDEF("9.6-2"), STRDEF("123456781234567812345678"), 0), NULL, "no path");
- storagePathCreateP(storageTest, STRDEF("archive/db/9.6-2/1234567812345678"));
+ HRN_STORAGE_PATH_CREATE(storageTest, "archive/db/9.6-2/1234567812345678");
TEST_RESULT_STR(
walSegmentFind(storageRepo(), STRDEF("9.6-2"), STRDEF("123456781234567812345678"), 0), NULL, "no segment");
TEST_ERROR(
@@ -252,6 +248,9 @@ testRun(void)
"HINT: check the PostgreSQL server log for errors.\n"
"HINT: run the 'start' command if the stanza was previously stopped.");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("timeout");
+
// Check timeout by making the wal segment appear after 250ms
HARNESS_FORK_BEGIN()
{
@@ -259,12 +258,9 @@ testRun(void)
{
sleepMSec(250);
- storagePutP(
- storageNewWriteP(
- storageTest,
- STRDEF(
- "archive/db/9.6-2/1234567812345678/123456781234567812345678-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
- NULL);
+ HRN_STORAGE_PUT_EMPTY(
+ storageTest,
+ "archive/db/9.6-2/1234567812345678/123456781234567812345678-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
HARNESS_FORK_CHILD_END();
@@ -278,11 +274,11 @@ testRun(void)
}
HARNESS_FORK_END();
- storagePutP(
- storageNewWriteP(
- storageTest,
- STRDEF("archive/db/9.6-2/1234567812345678/123456781234567812345678-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.gz")),
- NULL);
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("duplicate");
+
+ HRN_STORAGE_PUT_EMPTY(
+ storageTest, "archive/db/9.6-2/1234567812345678/123456781234567812345678-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.gz");
TEST_ERROR(
walSegmentFind(storageRepo(), STRDEF("9.6-2"), STRDEF("123456781234567812345678"), 0),
@@ -292,6 +288,9 @@ testRun(void)
", 123456781234567812345678-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.gz"
"\nHINT: are multiple primaries archiving to this stanza?");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("partial not found");
+
TEST_RESULT_STR(
walSegmentFind(storageRepo(), STRDEF("9.6-2"), STRDEF("123456781234567812345678.partial"), 0), NULL,
"did not find partial segment");
@@ -300,12 +299,19 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("walSegmentNext()"))
{
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("beginning and end range");
+
TEST_RESULT_STR_Z(
walSegmentNext(STRDEF("000000010000000100000001"), 16 * 1024 * 1024, PG_VERSION_10), "000000010000000100000002",
"get next");
TEST_RESULT_STR_Z(
walSegmentNext(STRDEF("0000000100000001000000FE"), 16 * 1024 * 1024, PG_VERSION_93), "0000000100000001000000FF",
"get next");
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("check overflow by version");
+
TEST_RESULT_STR_Z(
walSegmentNext(STRDEF("0000009900000001000000FF"), 16 * 1024 * 1024, PG_VERSION_93), "000000990000000200000000",
"get next overflow >= 9.3");
@@ -323,9 +329,16 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("walSegmentRange()"))
{
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("single segment");
+
TEST_RESULT_STRLST_Z(
walSegmentRange(STRDEF("000000010000000100000000"), 16 * 1024 * 1024, PG_VERSION_92, 1), "000000010000000100000000\n",
"get single");
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("check range by version");
+
TEST_RESULT_STRLST_Z(
walSegmentRange(STRDEF("0000000100000001000000FD"), 16 * 1024 * 1024, PG_VERSION_92, 4),
"0000000100000001000000FD\n0000000100000001000000FE\n000000010000000200000000\n000000010000000200000001\n",
diff --git a/test/src/module/command/archiveGetTest.c b/test/src/module/command/archiveGetTest.c
index 85db670d5..d7ea72d91 100644
--- a/test/src/module/command/archiveGetTest.c
+++ b/test/src/module/command/archiveGetTest.c
@@ -23,20 +23,25 @@ testRun(void)
if (testBegin("queueNeed()"))
{
StringList *argList = strLstNew();
- strLstAddZ(argList, "--stanza=test1");
- strLstAddZ(argList, "--archive-async");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
hrnCfgArgRawZ(argList, cfgOptPgPath, "/unused");
- strLstAddZ(argList, "--spool-path=" TEST_PATH "/spool");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
size_t queueSize = 16 * 1024 * 1024;
size_t walSegmentSize = 16 * 1024 * 1024;
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("path missing");
+
TEST_ERROR(
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_92),
PathMissingError, "unable to list file info for missing path '" TEST_PATH "/spool/archive/test1/in'");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("queue size too small");
+
HRN_STORAGE_PATH_CREATE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN);
TEST_RESULT_STRLST_Z(
@@ -44,6 +49,8 @@ testRun(void)
"000000010000000100000001\n000000010000000100000002\n", "queue size smaller than min");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("queue empty");
+
queueSize = (16 * 1024 * 1024) * 3;
TEST_RESULT_STRLST_Z(
@@ -51,6 +58,8 @@ testRun(void)
"000000010000000100000001\n000000010000000100000002\n000000010000000100000003\n", "empty queue");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("pg version earlier than 9.3");
+
Buffer *walSegmentBuffer = bufNew(walSegmentSize);
memset(bufPtr(walSegmentBuffer), 0, walSegmentSize);
@@ -61,8 +70,7 @@ testRun(void)
queueNeed(STRDEF("0000000100000001000000FE"), false, queueSize, walSegmentSize, PG_VERSION_92),
"000000010000000200000000\n000000010000000200000001\n", "queue has wal < 9.3");
- TEST_RESULT_STRLST_Z(
- storageListP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_IN)), "0000000100000001000000FE\n", "check queue");
+ TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "0000000100000001000000FE\n", .comment = "check queue");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("pg >= 9.3 and ok/junk status files");
@@ -341,25 +349,28 @@ testRun(void)
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
- #define TEST_WARN \
- "repo2: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id" \
- " '18072658121562454734'"
-
TEST_RESULT_LOG(
"P00 INFO: get 3 WAL file(s) from archive: 0000000100000001000000FE...000000010000000200000000\n"
- "P00 WARN: " TEST_WARN "\n"
+ "P00 WARN: repo2: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'\n"
"P01 DETAIL: found 0000000100000001000000FE in the repo1: 10-1 archive\n"
"P00 DETAIL: unable to find 0000000100000001000000FF in the archive");
TEST_STORAGE_GET(
- storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE.ok", "0\n" TEST_WARN, .remove = true);
+ storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE.ok",
+ "0\n"
+ "repo2: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'",
+ .remove = true);
TEST_STORAGE_GET(
- storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF.ok", "0\n" TEST_WARN, .remove = true);
+ storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF.ok",
+ "0\n"
+ "repo2: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'",
+ .remove = true);
TEST_STORAGE_GET_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE", .remove = true);
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN);
- #undef TEST_WARN
-
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("error on duplicates now that no segments are missing, repo with bad perms");
@@ -379,17 +390,12 @@ testRun(void)
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
- #define TEST_WARN1 \
- "repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1" \
- "/0000000100000001': [13] Permission denied"
- #define TEST_WARN2 \
- "repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1" \
- "/0000000100000002': [13] Permission denied"
-
TEST_RESULT_LOG(
"P00 INFO: get 3 WAL file(s) from archive: 0000000100000001000000FE...000000010000000200000000\n"
- "P00 WARN: " TEST_WARN1 "\n"
- "P00 WARN: " TEST_WARN2 "\n"
+ "P00 WARN: repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1"
+ "/0000000100000001': [13] Permission denied\n"
+ "P00 WARN: repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1"
+ "/0000000100000002': [13] Permission denied\n"
"P01 DETAIL: found 0000000100000001000000FE in the repo1: 10-1 archive\n"
"P01 DETAIL: found 0000000100000001000000FF in the repo1: 10-1 archive\n"
"P00 WARN: [ArchiveDuplicateError] duplicates found for WAL segment 000000010000000200000000:\n"
@@ -399,10 +405,18 @@ testRun(void)
TEST_STORAGE_GET_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE", .remove = true);
TEST_STORAGE_GET(
- storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE.ok", "0\n" TEST_WARN1, .remove = true);
+ storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FE.ok",
+ "0\n"
+ "repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1/0000000100000001':"
+ " [13] Permission denied",
+ .remove = true);
TEST_STORAGE_GET_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF", .remove = true);
TEST_STORAGE_GET(
- storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF.ok", "0\n" TEST_WARN1, .remove = true);
+ storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/0000000100000001000000FF.ok",
+ "0\n"
+ "repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1/0000000100000001':"
+ " [13] Permission denied",
+ .remove = true);
TEST_STORAGE_GET(
storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000200000000.error",
"45\n"
@@ -410,15 +424,13 @@ testRun(void)
"repo1: 10-1/0000000100000002/000000010000000200000000-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, 10-1/0000000100000002"
"/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
"HINT: are multiple primaries archiving to this stanza?\n"
- TEST_WARN2,
+ "repo2: [PathOpenError] unable to list file info for path '" TEST_PATH "/repo2/archive/test2/10-1" \
+ "/0000000100000002': [13] Permission denied",
.remove = true);
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN);
HRN_STORAGE_MODE(storageRepoIdxWrite(1), STORAGE_REPO_ARCHIVE "/10-1");
- #undef TEST_WARN1
- #undef TEST_WARN2
-
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("error on duplicates");
@@ -479,21 +491,21 @@ testRun(void)
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
- #define TEST_WARN1 \
- "repo3: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id" \
- " '18072658121562454734'"
- #define TEST_WARN2 \
- "repo1: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz" \
- " [FormatError] unexpected eof in compressed data"
-
TEST_RESULT_LOG(
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000200000000\n"
- "P00 WARN: " TEST_WARN1 "\n"
- "P01 WARN: " TEST_WARN2 "\n"
+ "P00 WARN: repo3: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'\n"
+ "P01 WARN: repo1: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data\n"
"P01 DETAIL: found 000000010000000200000000 in the repo2: 10-1 archive");
TEST_STORAGE_GET(
- storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000200000000.ok", "0\n" TEST_WARN1 "\n" TEST_WARN2,
+ storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000200000000.ok",
+ "0\n"
+ "repo3: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'\n"
+ "repo1: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data",
.remove = true);
TEST_STORAGE_GET_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000200000000", .remove = true);
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN);
@@ -511,24 +523,26 @@ testRun(void)
TEST_RESULT_VOID(cmdArchiveGetAsync(), "archive async");
- #define TEST_WARN3 \
- "repo2: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz" \
- " [FormatError] unexpected eof in compressed data"
-
TEST_RESULT_LOG(
"P00 INFO: get 1 WAL file(s) from archive: 000000010000000200000000\n"
- "P00 WARN: " TEST_WARN1 "\n"
+ "P00 WARN: repo3: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'\n"
"P01 WARN: [FileReadError] raised from local-1 shim protocol: unable to get 000000010000000200000000:\n"
- " " TEST_WARN2 "\n"
- " " TEST_WARN3);
+ " repo1: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data\n"
+ " repo2: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data");
TEST_STORAGE_GET(
storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000200000000.error",
"42\n"
"raised from local-1 shim protocol: unable to get 000000010000000200000000:\n"
- TEST_WARN2 "\n"
- TEST_WARN3 "\n"
- TEST_WARN1,
+ "repo1: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data\n"
+ "repo2: 10-1/0000000100000002/000000010000000200000000-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz"
+ " [FormatError] unexpected eof in compressed data\n"
+ "repo3: [ArchiveMismatchError] unable to retrieve the archive id for database version '10' and system-id"
+ " '18072658121562454734'",
.remove = true);
TEST_STORAGE_LIST(
storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000200000000.pgbackrest.tmp\n", .remove = true);
@@ -571,7 +585,6 @@ testRun(void)
{
harnessLogLevelSet(logLevelDetail);
- // Arguments that must be included. Use raw config here because we need to keep the
StringList *argBaseList = strLstNew();
hrnCfgArgRawZ(argBaseList, cfgOptPgPath, TEST_PATH "/pg");
hrnCfgArgRawZ(argBaseList, cfgOptRepoPath, TEST_PATH "/repo");
@@ -588,12 +601,16 @@ testRun(void)
TEST_ERROR(cmdArchiveGet(), HostInvalidError, "archive-get command must be run on the PostgreSQL host");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("segment parameter not specified");
+
argList = strLstDup(argBaseList);
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .exeBogus = true);
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "WAL segment to get required");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("path parameter not specified");
+
argList = strLstDup(argBaseList);
strLstAddZ(argList, "000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .exeBogus = true);
@@ -601,6 +618,8 @@ testRun(void)
TEST_ERROR(cmdArchiveGet(), ParamRequiredError, "path to copy WAL segment required");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("no valid repo");
+
HRN_STORAGE_PUT(
storagePgWrite(), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}));
@@ -623,10 +642,12 @@ testRun(void)
" scheme.");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("no valid repo - async");
+
argList = strLstDup(argBaseList);
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
strLstAddZ(argList, "00000001.history");
strLstAddZ(argList, TEST_PATH "/pg/pg_wal/RECOVERYHISTORY");
- strLstAddZ(argList, "--archive-async");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .exeBogus = true);
TEST_ERROR(cmdArchiveGet(), RepoInvalidError, "unable to find a valid repository");
@@ -643,8 +664,10 @@ testRun(void)
" HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving"
" scheme.");
- // Make sure the process times out when there is nothing to get
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("WAL not found - timeout");
+
+ // Make sure the process times out when there is nothing to get
argList = strLstDup(argBaseList);
hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
@@ -658,8 +681,9 @@ testRun(void)
cmdArchiveGet(), ArchiveTimeoutError,
"unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)");
- // Check for missing WAL
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("check for missing WAL");
+
HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok");
TEST_ERROR(
@@ -670,8 +694,9 @@ testRun(void)
storageExistsP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok")), false,
"check OK file was removed");
- // Write out a WAL segment for success
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("write WAL segment for success");
+
HRN_STORAGE_PATH_CREATE(storagePgWrite(), "pg_wal");
HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001", "SHOULD-BE-A-REAL-WAL-FILE");
@@ -682,11 +707,13 @@ testRun(void)
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_SPOOL_ARCHIVE_IN);
TEST_STORAGE_LIST(storagePgWrite(), "pg_wal", "RECOVERYXLOG\n", .remove = true);
- // Write more WAL segments (in this case queue should be full)
// -------------------------------------------------------------------------------------------------------------------------
- strLstAddZ(argList, "--archive-get-queue-max=48");
+ TEST_TITLE("write WAL segments for success - queue full");
+
+ hrnCfgArgRawZ(argList, cfgOptArchiveGetQueueMax, "48");
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .exeBogus = true);
+ // Write more WAL segments (in this case queue should be full)
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 "/000000010000000100000001.ok", "0\nwarning about x");
HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000002", "SHOULD-BE-A-REAL-WAL-FILE");
@@ -700,8 +727,10 @@ testRun(void)
TEST_STORAGE_LIST(storagePgWrite(), "pg_wal", "RECOVERYXLOG\n", .remove = true);
TEST_STORAGE_LIST(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN, "000000010000000100000002\n", .remove = true);
- // Make sure the process times out when it can't get a lock
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("unable to get lock");
+
+ // Make sure the process times out when it can't get a lock
HARNESS_FORK_BEGIN()
{
HARNESS_FORK_CHILD_BEGIN(0, true)
@@ -749,6 +778,8 @@ testRun(void)
HARNESS_FORK_END();
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("too many parameters specified");
+
strLstAddZ(argList, BOGUS_STR);
HRN_CFG_LOAD(cfgCmdArchiveGet, argList, .exeBogus = true);
@@ -1029,9 +1060,9 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("unable to get from one repo");
- HRN_STORAGE_PUT(
+ HRN_STORAGE_PUT_EMPTY(
storageRepoIdxWrite(0),
- STORAGE_REPO_ARCHIVE "/10-2/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz", NULL);
+ STORAGE_REPO_ARCHIVE "/10-2/01ABCDEF01ABCDEF01ABCDEF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.gz");
TEST_RESULT_INT(cmdArchiveGet(), 0, "get");
@@ -1070,8 +1101,7 @@ testRun(void)
TEST_RESULT_INT(cmdArchiveGet(), 0, "get");
- TEST_RESULT_LOG(
- "P00 INFO: found 01ABCDEF01ABCDEF01ABCDEF in the repo2: 10-1 archive");
+ TEST_RESULT_LOG("P00 INFO: found 01ABCDEF01ABCDEF01ABCDEF in the repo2: 10-1 archive");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("no segments to find with existing ok file");
diff --git a/test/src/module/command/archivePushTest.c b/test/src/module/command/archivePushTest.c
index 4feab2291..eeaeaa242 100644
--- a/test/src/module/command/archivePushTest.c
+++ b/test/src/module/command/archivePushTest.c
@@ -28,47 +28,44 @@ testRun(void)
if (testBegin("archivePushReadyList(), archivePushProcessList(), and archivePushDrop()"))
{
StringList *argList = strLstNew();
- strLstAddZ(argList, "--stanza=db");
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/db");
- strLstAddZ(argList, "--spool-path=" TEST_PATH "/spool");
- strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
+ hrnCfgArgRawZ(argList, cfgOptStanza, "db");
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/db");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleAsync);
- storagePathCreateP(storagePgWrite(), STRDEF("pg_wal/archive_status"));
- storagePathCreateP(storageTest, STRDEF("spool/archive/db/out"));
+ HRN_STORAGE_PATH_CREATE(storagePgWrite(), "pg_wal/archive_status");
+ HRN_STORAGE_PATH_CREATE(storageTest, "spool/archive/db/out");
// Create ok files to indicate WAL that has already been archived
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok")), NULL);
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000003.ok")), NULL);
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000004.ok")), NULL);
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000005.error")), NULL);
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000006.error")), NULL);
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/global.error")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000003.ok");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000004.ok");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000005.error");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000006.error");
+ HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/global.error");
// Create ready files for wal that still needs to be archived
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000002.ready")), NULL);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000003.ready")), NULL);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000005.ready")), NULL);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000006.ready")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000002.ready");
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000003.ready");
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000005.ready");
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000006.ready");
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("ready list");
TEST_RESULT_STRLST_Z(
archivePushProcessList(STRDEF(TEST_PATH "/db/pg_wal")),
"000000010000000100000002\n000000010000000100000005\n000000010000000100000006\n", "ready list");
- TEST_RESULT_STRLST_Z(
- strLstSort(storageListP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT)), sortOrderAsc),
- "000000010000000100000003.ok\n", "remaining status list");
+ TEST_STORAGE_LIST(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT, "000000010000000100000003.ok\n", .comment = "remaining status list");
- // Test drop
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("WAL drop");
+
StringList *argListDrop = strLstDup(argList);
- strLstAdd(argListDrop, strNewFmt("--archive-push-queue-max=%zu", (size_t)1024 * 1024 * 1024));
+ hrnCfgArgRawFmt(argListDrop, cfgOptArchivePushQueueMax, "%zu", (size_t)1024 * 1024 * 1024);
HRN_CFG_LOAD(cfgCmdArchivePush, argListDrop, .role = cfgCmdRoleAsync);
// Write the files that we claim are in pg_wal
@@ -77,50 +74,48 @@ testRun(void)
memset(bufPtr(walBuffer), 0, bufSize(walBuffer));
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}, walBuffer);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000002")), walBuffer);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000003")), walBuffer);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000005")), walBuffer);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000006")), walBuffer);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000002", walBuffer);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000003", walBuffer);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000005", walBuffer);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000006", walBuffer);
// Queue max is high enough that no WAL will be dropped
TEST_RESULT_BOOL(
- archivePushDrop(STRDEF("pg_wal"), archivePushProcessList(STRDEF(TEST_PATH "/db/pg_wal"))), false,
- "wal is not dropped");
+ archivePushDrop(STRDEF("pg_wal"), archivePushProcessList(STRDEF(TEST_PATH "/db/pg_wal"))), false, "wal is not dropped");
// Now set queue max low enough that WAL will be dropped
argListDrop = strLstDup(argList);
- strLstAdd(argListDrop, strNewFmt("--archive-push-queue-max=%zu", (size_t)16 * 1024 * 1024 * 2));
+ hrnCfgArgRawFmt(argListDrop, cfgOptArchivePushQueueMax, "%zu", (size_t)16 * 1024 * 1024 * 2);
HRN_CFG_LOAD(cfgCmdArchivePush, argListDrop, .role = cfgCmdRoleAsync);
TEST_RESULT_BOOL(
- archivePushDrop(STRDEF("pg_wal"), archivePushProcessList(STRDEF(TEST_PATH "/db/pg_wal"))), true,
- "wal is dropped");
+ archivePushDrop(STRDEF("pg_wal"), archivePushProcessList(STRDEF(TEST_PATH "/db/pg_wal"))), true, "wal is dropped");
}
// *****************************************************************************************************************************
if (testBegin("archivePushCheck()"))
{
StringList *argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/pg");
- strLstAddZ(argList, "--repo1-path=" TEST_PATH "/repo");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
- // Check mismatched pg_control and archive.info
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
+ TEST_TITLE("mismatched pg_control and archive.info - pg version");
+
+ HRN_STORAGE_PUT(
+ storageTest, "pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_96, .systemId = 0xFACEFACEFACEFACE}));
// Create incorrect archive info
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n");
TEST_ERROR(
archivePushCheck(true), RepoInvalidError,
@@ -129,15 +124,17 @@ testRun(void)
" 9.4, system-id 5555555555555555555"
"\nHINT: are you archiving to the correct stanza?");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("mismatched pg_control and archive.info - system-id");
+
// Fix the version
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":5555555555555555555,\"db-version\":\"9.6\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":5555555555555555555,\"db-version\":\"9.6\"}\n");
TEST_ERROR(
archivePushCheck(true), RepoInvalidError,
@@ -146,15 +143,17 @@ testRun(void)
" 9.6, system-id 5555555555555555555"
"\nHINT: are you archiving to the correct stanza?");
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("pg_control and archive.info match");
+
// Fix archive info
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n");
ArchivePushCheckResult result = {0};
TEST_ASSIGN(result, archivePushCheck(true), "get archive check result");
@@ -172,30 +171,28 @@ testRun(void)
TEST_TITLE("mismatched repos when pg-path not present");
argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
- strLstAddZ(argList, "--repo2-path=" TEST_PATH "/repo2");
- strLstAddZ(argList, "--repo4-path=" TEST_PATH "/repo4");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
+ hrnCfgArgKeyRawZ(argList, cfgOptRepoPath, 2, TEST_PATH "/repo2");
+ hrnCfgArgKeyRawZ(argList, cfgOptRepoPath, 4, TEST_PATH "/repo4");
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
// repo2 has correct info
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo2/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n");
// repo4 has incorrect info
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo4/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(1), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n");
TEST_ASSIGN(result, archivePushCheck(false), "get archive check result");
@@ -218,15 +215,14 @@ testRun(void)
TEST_TITLE("matched repos when pg-path not present");
// repo4 has correct info
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo4/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=2\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n"
- "2={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(1), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=2\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":5555555555555555555,\"db-version\":\"9.4\"}\n"
+ "2={\"db-id\":18072658121562454734,\"db-version\":\"9.6\"}\n");
TEST_ASSIGN(result, archivePushCheck(false), "get archive check result");
@@ -249,24 +245,29 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("Synchronous cmdArchivePush() and archivePushFile()"))
{
+ // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("command must be run on the pg host");
StringList *argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptPgHost, "host");
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg");
- strLstAddZ(argList, "--" CFGOPT_STANZA "=test2");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test2");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleMain);
TEST_ERROR(cmdArchivePush(), HostInvalidError, "archive-push command must be run on the PostgreSQL host");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("WAL segment not specified");
+
argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
TEST_ERROR(cmdArchivePush(), ParamRequiredError, "WAL segment to push required");
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("pg-path not specified");
+
StringList *argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
@@ -277,36 +278,36 @@ testRun(void)
"\nHINT: is %f passed to archive-push instead of %p?"
"\nHINT: PostgreSQL may pass relative paths even with %p depending on the environment.");
- // Create pg_control and archive.info
// -------------------------------------------------------------------------------------------------------------------------
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/pg");
- strLstAddZ(argList, "--repo1-path=" TEST_PATH "/repo");
+ TEST_TITLE("attempt to push WAL with incorrect headers");
+
+ // Create pg_control and archive.info
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
+ HRN_STORAGE_PUT(
+ storageTest, "pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_11, .systemId = 0xFACEFACEFACEFACE}));
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}\n"));
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}\n");
// Generate WAL with incorrect headers and try to push them
- // -------------------------------------------------------------------------------------------------------------------------
Buffer *walBuffer1 = bufNew((size_t)16 * 1024 * 1024);
bufUsedSet(walBuffer1, bufSize(walBuffer1));
memset(bufPtr(walBuffer1), 0, bufSize(walBuffer1));
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_10, .systemId = 0xFACEFACEFACEFACE}, walBuffer1);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000001")), walBuffer1);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000001", walBuffer1);
THROW_ON_SYS_ERROR(chdir(strZ(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
@@ -319,7 +320,7 @@ testRun(void)
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_11, .systemId = 0xECAFECAFECAFECAF}, walBuffer1);
const char *walBuffer1Sha1 = strZ(bufHex(cryptoHashOne(HASH_TYPE_SHA1_STR, walBuffer1)));
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000001")), walBuffer1);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000001", walBuffer1);
TEST_ERROR(
cmdArchivePush(), ArchiveMismatchError,
@@ -330,24 +331,20 @@ testRun(void)
TEST_TITLE("push by ignoring the invalid header");
argListTemp = strLstDup(argList);
- hrnCfgArgRawNegate(argListTemp, cfgOptArchiveHeaderCheck);
+ hrnCfgArgRawBool(argListTemp, cfgOptArchiveHeaderCheck, false);
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '000000010000000100000001' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageRepoIdx(0),
- strNewFmt(STORAGE_REPO_ARCHIVE "/11-1/000000010000000100000001-%s.gz", walBuffer1Sha1)),
- true, "check repo for WAL file");
TEST_STORAGE_EXISTS(
storageRepoIdxWrite(0), strZ(strNewFmt(STORAGE_REPO_ARCHIVE "/11-1/000000010000000100000001-%s.gz", walBuffer1Sha1)),
- .remove = true);
+ .remove = true, .comment = "check repo for WAL file, then remove");
- // Generate valid WAL and push them
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("generate valid WAL and push them");
+
argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
@@ -361,15 +358,14 @@ testRun(void)
(TEST_BIG_ENDIAN() ? "1c5f963d720bb199d7935dbd315447ea2ec3feb2" : "aae7591a1dbc58f21d0d004886075094f622e6dd") :
"28a13fd8cf6fcd9f9a8108aed4c8bcc58040863a";
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000001")), walBuffer1);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000001", walBuffer1);
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '000000010000000100000001' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/11-1/0000000100000001/000000010000000100000001-%s.gz", walBuffer1Sha1)),
- true, "check repo for WAL file");
+ TEST_STORAGE_EXISTS(
+ storageRepoIdxWrite(0), strZ(strNewFmt(STORAGE_REPO_ARCHIVE "/11-1/000000010000000100000001-%s.gz", walBuffer1Sha1)),
+ .comment = "check repo for WAL file");
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment again");
TEST_RESULT_LOG(
@@ -384,7 +380,7 @@ testRun(void)
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_11, .systemId = 0xFACEFACEFACEFACE}, walBuffer2);
const char *walBuffer2Sha1 = strZ(bufHex(cryptoHashOne(HASH_TYPE_SHA1_STR, walBuffer2)));
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/000000010000000100000001")), walBuffer2);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_wal/000000010000000100000001", walBuffer2);
TEST_ERROR(
cmdArchivePush(), ArchiveDuplicateError,
@@ -394,58 +390,58 @@ testRun(void)
TEST_TITLE("WAL with absolute path and no pg1-path");
argListTemp = strLstNew();
- strLstAddZ(argListTemp, "--" CFGOPT_STANZA "=test");
+ hrnCfgArgRawZ(argListTemp, cfgOptStanza, "test");
hrnCfgArgRawZ(argListTemp, cfgOptRepoPath, TEST_PATH "/repo");
strLstAddZ(argListTemp, TEST_PATH "/pg/pg_wal/000000010000000100000002");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
- TEST_RESULT_VOID(
- storagePutP(storageNewWriteP(storageTest, STRDEF("pg/pg_wal/000000010000000100000002")), walBuffer2), "write WAL");
+ HRN_STORAGE_PUT(storageTest, "pg/pg_wal/000000010000000100000002", walBuffer2, .comment = "write WAL");
// Create tmp file to make it look like a prior push failed partway through to ensure that retries work
- TEST_RESULT_VOID(
- storagePutP(
- storageNewWriteP(
- storageTest,
- strNewFmt("repo/archive/test/11-1/0000000100000001/000000010000000100000002-%s.gz.pgbackrest.tmp",
- walBuffer2Sha1)),
- BUFSTRDEF("PARTIAL")),
- "write WAL tmp file");
+ HRN_STORAGE_PUT_Z(
+ storageTest,
+ strZ(
+ strNewFmt("repo/archive/test/11-1/0000000100000001/000000010000000100000002-%s.gz.pgbackrest.tmp", walBuffer2Sha1)),
+ "PARTIAL", .comment = "write WAL tmp file");
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '000000010000000100000002' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/11-1/0000000100000001/000000010000000100000002-%s.gz", walBuffer2Sha1)),
- true, "check repo for WAL file");
+ TEST_STORAGE_EXISTS(
+ storageRepoIdxWrite(0),
+ strZ(
+ strNewFmt(
+ STORAGE_REPO_ARCHIVE "/11-1/0000000100000001/000000010000000100000002-%s.gz", walBuffer2Sha1)),
+ .comment = "check repo for WAL file");
TEST_RESULT_BOOL(
storageExistsP(
storageTest,
strNewFmt("repo/archive/test/11-1/0000000100000001/000000010000000100000002-%s.gz.pgbackrest.tmp", walBuffer2Sha1)),
false, "check WAL tmp file is gone");
- // Push a history file
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("push a history file");
+
argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, "pg_wal/00000001.history");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/00000001.history")), BUFSTRDEF("FAKEHISTORY"));
+ HRN_STORAGE_PUT_Z(storagePgWrite(), "pg_wal/00000001.history", "FAKEHISTORY");
TEST_RESULT_VOID(cmdArchivePush(), "push a history file");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '00000001.history' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(storageTest, STRDEF("repo/archive/test/11-1/00000001.history")), true, "check repo for history file");
+ TEST_STORAGE_EXISTS(
+ storageRepoIdx(0), STORAGE_REPO_ARCHIVE "/11-1/00000001.history", .comment = "check repo for history file");
- // Check drop functionality
// -------------------------------------------------------------------------------------------------------------------------
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000001.ready")), NULL);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_wal/archive_status/000000010000000100000002.ready")), NULL);
+ TEST_TITLE("check drop functionality");
+
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000001.ready");
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_wal/archive_status/000000010000000100000002.ready");
argListTemp = strLstDup(argList);
- strLstAddZ(argListTemp, "--archive-push-queue-max=16m");
+ hrnCfgArgRawZ(argListTemp, cfgOptArchivePushQueueMax, "16m");
strLstAddZ(argListTemp, "pg_wal/000000010000000100000002");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
@@ -453,7 +449,7 @@ testRun(void)
TEST_RESULT_LOG("P00 WARN: dropped WAL file '000000010000000100000002' because archive queue exceeded 16MB");
argListTemp = strLstDup(argList);
- strLstAddZ(argListTemp, "--archive-push-queue-max=1GB");
+ hrnCfgArgRawZ(argListTemp, cfgOptArchivePushQueueMax, "1GB");
strLstAddZ(argListTemp, "pg_wal/000000010000000100000002");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
@@ -469,36 +465,6 @@ testRun(void)
// Remove old repo
HRN_STORAGE_PATH_REMOVE(storageTest, "repo", .errorOnMissing = true, .recurse = true);
- // repo2 is encrypted
- StorageWrite *infoWrite = storageNewWriteP(storageTest, STRDEF("repo2/archive/test/archive.info"));
-
- ioFilterGroupAdd(
- ioWriteFilterGroup(storageWriteIo(infoWrite)), cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc,
- BUFSTRDEF("badpassphrase"), NULL));
-
- storagePutP(
- infoWrite,
- harnessInfoChecksumZ(
- "[cipher]\n"
- "cipher-pass=\"badsubpassphrase\"\n"
- "\n"
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}"));
-
- // repo3 is not encrypted
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo3/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}"));
-
- // Push encrypted WAL segment
argListTemp = strLstNew();
hrnCfgArgRawZ(argListTemp, cfgOptStanza, "test");
hrnCfgArgKeyRawZ(argListTemp, cfgOptPgPath, 1, TEST_PATH "/pg");
@@ -511,29 +477,43 @@ testRun(void)
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
hrnCfgEnvKeyRemoveRaw(cfgOptRepoCipherPass, 2);
+ // repo2 is encrypted
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE,
+ "[cipher]\n"
+ "cipher-pass=\"badsubpassphrase\"\n"
+ "\n"
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}",
+ .cipherType = cipherTypeAes256Cbc, .cipherPass = "badpassphrase");
+
+ // repo3 is not encrypted
+ HRN_INFO_PUT(
+ storageRepoIdxWrite(1), INFO_ARCHIVE_PATH_FILE,
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":18072658121562454734,\"db-version\":\"11\"}");
+
+ // Push encrypted WAL segment
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '000000010000000100000002' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo2/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo2 for WAL file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo2/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
+ .remove = true, .comment = "check repo2 for WAL file then remove");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo3/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo3 for WAL file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo3/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
+ .remove = true, .comment = "check repo3 for WAL file then remove");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("write error on one repo but other repo succeeds");
- storageRemoveP(
- storageTest, strNewFmt("repo2/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1),
- .errorOnMissing = true);
- storageRemoveP(
- storageTest, strNewFmt("repo3/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1),
- .errorOnMissing = true);
-
HRN_STORAGE_MODE(storageTest, "repo2/archive/test/11-1/0000000100000001", .mode = 0500);
TEST_ERROR(
@@ -544,14 +524,10 @@ testRun(void)
"repo2: [FileOpenError] unable to open file '" TEST_PATH "/repo2/archive/test/11-1/0000000100000001"
"/000000010000000100000002-%s' for write: [13] Permission denied", walBuffer2Sha1)));
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo2/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- false, "check repo2 for no WAL file");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo3/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo3 for WAL file");
+ TEST_STORAGE_LIST_EMPTY(storageTest, "repo2/archive/test/11-1/0000000100000001", .comment = "check repo2 for no WAL file");
+ TEST_STORAGE_LIST(
+ storageTest, "repo3/archive/test/11-1/0000000100000001",
+ strZ(strNewFmt("000000010000000100000002-%s\n", walBuffer2Sha1)), .comment = "check repo3 for WAL file");
HRN_STORAGE_MODE(storageTest, "repo2/archive/test/11-1/0000000100000001");
@@ -564,10 +540,9 @@ testRun(void)
" HINT: this is valid in some recovery scenarios but may also indicate a problem.\n"
"P00 INFO: pushed WAL file '000000010000000100000002' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo2/archive/test/11-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo2 for WAL file");
+ TEST_STORAGE_LIST(
+ storageTest, "repo2/archive/test/11-1/0000000100000001",
+ strZ(strNewFmt("000000010000000100000002-%s\n", walBuffer2Sha1)), .comment = "check repo2 for WAL file");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("WAL already exists in both repos");
@@ -639,6 +614,7 @@ testRun(void)
static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_ARCHIVE_PUSH_LIST};
hrnProtocolLocalShimInstall(testLocalHandlerList, PROTOCOL_SERVER_HANDLER_LIST_SIZE(testLocalHandlerList));
+ // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("command must be run on the pg host");
StringList *argList = strLstNew();
@@ -655,78 +631,80 @@ testRun(void)
TEST_TITLE("pg1-path must be set when async");
argList = strLstNew();
- strLstAddZ(argList, "--" CFGOPT_SPOOL_PATH "=/spool");
- strLstAddZ(argList, "--" CFGOPT_STANZA "=test2");
- strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, "/spool");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test2");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
strLstAddZ(argList, "/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleAsync);
TEST_ERROR(cmdArchivePush(), OptionRequiredError, "'archive-push' command in async mode requires option 'pg1-path'");
- // Call with a bogus exe name so the async process will error out and we can make sure timeouts work
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("check timeout on async error");
+
+ // Call with a bogus exe name so the async process will error out and we can make sure timeouts work
argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
- strLstAddZ(argList, "--archive-async");
- strLstAddZ(argList, "--archive-timeout=1");
- strLstAddZ(argList, "--spool-path=" TEST_PATH " /spool");
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/pg");
- strLstAddZ(argList, "--repo1-path=" TEST_PATH "/repo");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
+ hrnCfgArgRawZ(argList, cfgOptArchiveTimeout, "1");
strLstAddZ(argList, "pg_wal/bogus");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .exeBogus = true);
- storagePathCreateP(storageTest, cfgOptionStr(cfgOptPgPath));
+ HRN_STORAGE_PATH_CREATE(storageTest, strZ(cfgOptionStr(cfgOptPgPath)));
THROW_ON_SYS_ERROR(chdir(strZ(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
TEST_ERROR(
cmdArchivePush(), ArchiveTimeoutError,
"unable to push WAL file 'bogus' to the archive asynchronously after 1 second(s)");
- // Create pg_control and archive.info
+ // Create pg_control and archive.info for next set of tests
// -------------------------------------------------------------------------------------------------------------------------
argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
- strLstAddZ(argList, "--archive-async");
- strLstAddZ(argList, "--no-compress");
- strLstAddZ(argList, "--spool-path=" TEST_PATH "/spool");
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/pg");
- strLstAddZ(argList, "--repo1-path=" TEST_PATH "/repo");
- strLstAddZ(argList, "--log-subprocess");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
+ hrnCfgArgRawBool(argList, cfgOptCompress, false);
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
+ hrnCfgArgRawBool(argList, cfgOptLogSubprocess, true);
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)),
+ HRN_STORAGE_PUT(storageTest, "pg/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL,
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_94, .systemId = 0xAAAABBBBCCCCDDDD}));
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":12297848147757817309,\"db-version\":\"9.4\"}\n"));
+ HRN_INFO_PUT(
+ storageTest, "repo/archive/test/archive.info",
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":12297848147757817309,\"db-version\":\"9.4\"}\n");
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("async, ignore error file on first pass");
// Write out an error file that will be ignored on the first pass, then the async process will write a new one
- // -------------------------------------------------------------------------------------------------------------------------
StringList *argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, TEST_PATH "/pg/pg_xlog/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
- storagePathCreateP(storagePgWrite(), STRDEF("pg_xlog/archive_status"));
+ HRN_STORAGE_PATH_CREATE(storagePgWrite(), "pg_xlog/archive_status");
- storagePutP(
- storageNewWriteP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error")),
- BUFSTRDEF("25\nbogus error"));
+ HRN_STORAGE_PUT_Z(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.error", "25\nbogus error");
TEST_ERROR(cmdArchivePush(), AssertError, "no WAL files to process");
- storageRemoveP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/global.error"), .errorOnMissing = true);
+ TEST_STORAGE_EXISTS(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/global.error", .remove = true);
+
+ // -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("with lock, prevent async from running");
// Acquire a lock so the async process will not be able to run -- this will result in a timeout
- // -------------------------------------------------------------------------------------------------------------------------
argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, TEST_PATH "/pg/pg_xlog/000000010000000100000001");
- strLstAddZ(argListTemp, "--archive-timeout=1");
+ hrnCfgArgRawZ(argListTemp, cfgOptArchiveTimeout, "1");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
THROW_ON_SYS_ERROR(chdir(strZ(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
@@ -774,13 +752,15 @@ testRun(void)
}
HARNESS_FORK_END();
- // Actually push a WAL file
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("async WAL push");
+
+ // Actually push a WAL file
argListTemp = strLstDup(argList);
strLstAddZ(argListTemp, TEST_PATH "/pg/pg_xlog/000000010000000100000001");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp);
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/archive_status/000000010000000100000001.ready")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_xlog/archive_status/000000010000000100000001.ready");
Buffer *walBuffer1 = bufNew((size_t)16 * 1024 * 1024);
bufUsedSet(walBuffer1, bufSize(walBuffer1));
@@ -788,51 +768,50 @@ testRun(void)
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_94, .systemId = 0xAAAABBBBCCCCDDDD}, walBuffer1);
const char *walBuffer1Sha1 = strZ(bufHex(cryptoHashOne(HASH_TYPE_SHA1_STR, walBuffer1)));
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/000000010000000100000001")), walBuffer1);
+ HRN_STORAGE_PUT(storagePgWrite(),"pg_xlog/000000010000000100000001", walBuffer1);
TEST_RESULT_VOID(cmdArchivePush(), "push the WAL segment");
TEST_RESULT_LOG("P00 INFO: pushed WAL file '000000010000000100000001' to the archive asynchronously");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
- true, "check repo for WAL file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
+ .comment = "check repo for WAL file");
- // Direct tests of the async function
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("direct tests of the async function");
+
argList = strLstNew();
- strLstAddZ(argList, "--stanza=test");
+ hrnCfgArgRawZ(argList, cfgOptSpoolPath, TEST_PATH "/spool");
+ hrnCfgArgRawZ(argList, cfgOptStanza, "test");
+ hrnCfgArgRawBool(argList, cfgOptArchiveAsync, true);
+ hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
+ hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
+ hrnCfgArgRawBool(argList, cfgOptLogSubprocess, true);
hrnCfgArgRawZ(argList, cfgOptCompressType, "none");
- strLstAddZ(argList, "--spool-path=" TEST_PATH "/spool");
- strLstAddZ(argList, "--" CFGOPT_ARCHIVE_ASYNC);
- strLstAddZ(argList, "--pg1-path=" TEST_PATH "/pg");
- strLstAddZ(argList, "--repo1-path=" TEST_PATH "/repo");
- strLstAddZ(argList, "--log-subprocess");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleAsync);
TEST_ERROR(cmdArchivePushAsync(), ParamRequiredError, "WAL path to push required");
- // Check that global.error is created
// -------------------------------------------------------------------------------------------------------------------------
+ TEST_TITLE("async, check that global.error is created");
+
// Remove data from prior tests
HRN_STORAGE_PATH_REMOVE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT, .recurse = true);
- storagePathCreateP(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT_STR);
+ HRN_STORAGE_PATH_CREATE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT);
HRN_STORAGE_PATH_REMOVE(storagePgWrite(), "pg_xlog/archive_status", .recurse = true);
- storagePathCreateP(storagePgWrite(), STRDEF("pg_xlog/archive_status"));
+ HRN_STORAGE_PATH_CREATE(storagePgWrite(), "pg_xlog/archive_status");
strLstAddZ(argList, TEST_PATH "/pg/pg_xlog");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleAsync);
TEST_ERROR(cmdArchivePushAsync(), AssertError, "no WAL files to process");
- TEST_RESULT_STR_Z(
- strNewBuf(storageGetP(storageNewReadP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/global.error")))),
- "25\nno WAL files to process", "check global.error");
+ TEST_STORAGE_GET(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT "/global.error", "25\nno WAL files to process",
+ .comment = "check global.error");
- TEST_RESULT_STRLST_Z(
- strLstSort(storageListP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT)), sortOrderAsc),
- "global.error\n", "check status files");
+ TEST_STORAGE_LIST(storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT, "global.error\n", .comment = "check status files");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("add repo, push already pushed WAL and new WAL");
@@ -841,25 +820,23 @@ testRun(void)
hrnCfgArgKeyRawZ(argList, cfgOptRepoPath, 3, TEST_PATH "/repo3");
HRN_CFG_LOAD(cfgCmdArchivePush, argList, .role = cfgCmdRoleAsync);
- storagePutP(
- storageNewWriteP(storageTest, STRDEF("repo3/archive/test/archive.info")),
- harnessInfoChecksumZ(
- "[db]\n"
- "db-id=1\n"
- "\n"
- "[db:history]\n"
- "1={\"db-id\":12297848147757817309,\"db-version\":\"9.4\"}\n"));
+ HRN_INFO_PUT(
+ storageTest, "repo3/archive/test/archive.info",
+ "[db]\n"
+ "db-id=1\n"
+ "\n"
+ "[db:history]\n"
+ "1={\"db-id\":12297848147757817309,\"db-version\":\"9.4\"}\n");
// Recreate ready file for WAL 1
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/archive_status/000000010000000100000001.ready")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_xlog/archive_status/000000010000000100000001.ready");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
- true, "check repo1 for WAL 1 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
+ .comment = "check repo1 for WAL 1 file");
// Create a ready file for WAL 2 but don't create the segment yet -- this will test the file error
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/archive_status/000000010000000100000002.ready")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_xlog/archive_status/000000010000000100000002.ready");
TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments");
TEST_RESULT_LOG_FMT(
@@ -871,19 +848,19 @@ testRun(void)
"[55] raised from local-1 shim protocol: " STORAGE_ERROR_READ_MISSING,
TEST_PATH "/pg/pg_xlog/000000010000000100000002");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
- true, "check repo1 for WAL 1 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
+ .comment = "check repo1 for WAL 1 file");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
- true, "check repo3 for WAL 1 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo3/archive/test/9.4-1/0000000100000001/000000010000000100000001-%s", walBuffer1Sha1)),
+ .comment = "check repo3 for WAL 1 file");
- TEST_RESULT_STRLST_Z(
- strLstSort(storageListP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT)), sortOrderAsc),
- "000000010000000100000001.ok\n000000010000000100000002.error\n", "check status files");
+ TEST_STORAGE_LIST(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT,
+ "000000010000000100000001.ok\n"
+ "000000010000000100000002.error\n",
+ .comment = "check status files");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("create and push previously missing WAL");
@@ -895,10 +872,10 @@ testRun(void)
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_94, .systemId = 0xAAAABBBBCCCCDDDD}, walBuffer2);
const char *walBuffer2Sha1 = strZ(bufHex(cryptoHashOne(HASH_TYPE_SHA1_STR, walBuffer2)));
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/000000010000000100000002")), walBuffer2);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_xlog/000000010000000100000002", walBuffer2);
argListTemp = strLstDup(argList);
- strLstAddZ(argListTemp, "--archive-push-queue-max=1gb");
+ hrnCfgArgRawZ(argListTemp, cfgOptArchivePushQueueMax, "1gb");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp, .role = cfgCmdRoleAsync);
TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments");
@@ -906,24 +883,24 @@ testRun(void)
"P00 INFO: push 1 WAL file(s) to archive: 000000010000000100000002\n"
"P01 DETAIL: pushed WAL file '000000010000000100000002' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo1 for WAL 2 file");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo3/archive/test/9.4-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
- true, "check repo3 for WAL 2 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
+ .comment = "check repo1 for WAL 2 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo3/archive/test/9.4-1/0000000100000001/000000010000000100000002-%s", walBuffer2Sha1)),
+ .comment = "check repo3 for WAL 2 file");
- TEST_RESULT_STRLST_Z(
- strLstSort(storageListP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT)), sortOrderAsc),
- "000000010000000100000001.ok\n000000010000000100000002.ok\n", "check status files");
+ TEST_STORAGE_LIST(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT,
+ "000000010000000100000001.ok\n"
+ "000000010000000100000002.ok\n",
+ .comment = "check status files");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("push wal 2 again to get warnings from both repos");
// Remove the OK file so the WAL gets pushed again
- storageRemoveP(storageSpoolWrite(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000002.ok"));
+ HRN_STORAGE_REMOVE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000002.ok");
TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments");
TEST_RESULT_LOG(
@@ -944,36 +921,34 @@ testRun(void)
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_94, .systemId = 0xAAAABBBBCCCCDDDD}, walBuffer3);
const char *walBuffer3Sha1 = strZ(bufHex(cryptoHashOne(HASH_TYPE_SHA1_STR, walBuffer3)));
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/000000010000000100000003")), walBuffer3);
+ HRN_STORAGE_PUT(storagePgWrite(), "pg_xlog/000000010000000100000003", walBuffer3);
// Create ready file
- storagePutP(storageNewWriteP(storagePgWrite(), STRDEF("pg_xlog/archive_status/000000010000000100000003.ready")), NULL);
+ HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "pg_xlog/archive_status/000000010000000100000003.ready");
TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segment");
TEST_RESULT_LOG(
"P00 INFO: push 1 WAL file(s) to archive: 000000010000000100000003\n"
"P01 DETAIL: pushed WAL file '000000010000000100000003' to the archive");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000003-%s", walBuffer3Sha1)),
- true, "check repo1 for WAL 3 file");
- TEST_RESULT_BOOL(
- storageExistsP(
- storageTest, strNewFmt("repo3/archive/test/9.4-1/0000000100000001/000000010000000100000003-%s", walBuffer3Sha1)),
- true, "check repo3 for WAL 3 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo/archive/test/9.4-1/0000000100000001/000000010000000100000003-%s", walBuffer3Sha1)),
+ .comment = "check repo1 for WAL 3 file");
+ TEST_STORAGE_EXISTS(
+ storageTest, strZ(strNewFmt("repo3/archive/test/9.4-1/0000000100000001/000000010000000100000003-%s", walBuffer3Sha1)),
+ .comment = "check repo3 for WAL 3 file");
// Remove the ready file to prevent WAL 3 from being considered for the next test
- storageRemoveP(storagePgWrite(), STRDEF("pg_xlog/archive_status/000000010000000100000003.ready"), .errorOnMissing = true);
+ HRN_STORAGE_REMOVE(storagePgWrite(), "pg_xlog/archive_status/000000010000000100000003.ready", .errorOnMissing = true);
// Check that drop functionality works
// -------------------------------------------------------------------------------------------------------------------------
// Remove status files
HRN_STORAGE_PATH_REMOVE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT, .recurse = true);
- storagePathCreateP(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT_STR);
+ HRN_STORAGE_PATH_CREATE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_OUT);
argListTemp = strLstDup(argList);
- strLstAddZ(argListTemp, "--archive-push-queue-max=16m");
+ hrnCfgArgRawZ(argListTemp, cfgOptArchivePushQueueMax, "16m");
HRN_CFG_LOAD(cfgCmdArchivePush, argListTemp, .role = cfgCmdRoleAsync);
TEST_RESULT_VOID(cmdArchivePushAsync(), "push WAL segments");
@@ -982,19 +957,19 @@ testRun(void)
"P00 WARN: dropped WAL file '000000010000000100000001' because archive queue exceeded 16MB\n"
"P00 WARN: dropped WAL file '000000010000000100000002' because archive queue exceeded 16MB");
- TEST_RESULT_STR_Z(
- strNewBuf(
- storageGetP(storageNewReadP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok")))),
- "0\ndropped WAL file '000000010000000100000001' because archive queue exceeded 16MB", "check WAL 1 warning");
+ TEST_STORAGE_GET(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000001.ok",
+ "0\ndropped WAL file '000000010000000100000001' because archive queue exceeded 16MB", .comment = "check WAL 1 warning");
- TEST_RESULT_STR_Z(
- strNewBuf(
- storageGetP(storageNewReadP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000002.ok")))),
- "0\ndropped WAL file '000000010000000100000002' because archive queue exceeded 16MB", "check WAL 2 warning");
+ TEST_STORAGE_GET(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT "/000000010000000100000002.ok",
+ "0\ndropped WAL file '000000010000000100000002' because archive queue exceeded 16MB", .comment = "check WAL 2 warning");
- TEST_RESULT_STRLST_Z(
- strLstSort(storageListP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_OUT)), sortOrderAsc),
- "000000010000000100000001.ok\n000000010000000100000002.ok\n", "check status files");
+ TEST_STORAGE_LIST(
+ storageSpool(), STORAGE_SPOOL_ARCHIVE_OUT,
+ "000000010000000100000001.ok\n"
+ "000000010000000100000002.ok\n",
+ .comment = "check status files");
// Uninstall local command handler shim
hrnProtocolLocalShimUninstall();