2018-04-29 10:16:59 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Test Archive Common
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2018-09-16 14:12:53 -04:00
|
|
|
#include "storage/helper.h"
|
2018-09-14 16:08:33 -04:00
|
|
|
#include "storage/driver/posix/storage.h"
|
|
|
|
|
|
|
|
#include "common/harnessConfig.h"
|
2018-09-07 08:00:18 -07:00
|
|
|
|
2018-04-29 10:16:59 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Test Run
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
void
|
2018-08-03 19:19:14 -04:00
|
|
|
testRun(void)
|
2018-04-29 10:16:59 -04:00
|
|
|
{
|
2018-05-18 11:57:32 -04:00
|
|
|
FUNCTION_HARNESS_VOID();
|
|
|
|
|
2018-09-07 08:00:18 -07:00
|
|
|
// Create default storage object for testing
|
2018-09-14 16:08:33 -04:00
|
|
|
Storage *storageTest = storageDriverPosixInterface(
|
|
|
|
storageDriverPosixNew(strNew(testPath()), STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL));
|
2018-09-07 08:00:18 -07:00
|
|
|
|
2018-04-29 10:16:59 -04:00
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("archiveAsyncStatus()"))
|
|
|
|
{
|
|
|
|
StringList *argList = strLstNew();
|
|
|
|
strLstAddZ(argList, "pgbackrest");
|
|
|
|
strLstAdd(argList, strNewFmt("--spool-path=%s", testPath()));
|
|
|
|
strLstAddZ(argList, "--archive-async");
|
|
|
|
strLstAddZ(argList, "--archive-timeout=1");
|
|
|
|
strLstAddZ(argList, "--stanza=db");
|
|
|
|
strLstAddZ(argList, "archive-push");
|
|
|
|
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
String *segment = strNew("000000010000000100000001");
|
|
|
|
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), false, "directory and status file not present");
|
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModeGet, segment, false), false, "directory and status file not present");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
mkdir(strPtr(strNewFmt("%s/archive", testPath())), 0750);
|
|
|
|
mkdir(strPtr(strNewFmt("%s/archive/db", testPath())), 0750);
|
|
|
|
mkdir(strPtr(strNewFmt("%s/archive/db/out", testPath())), 0750);
|
|
|
|
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), false, "status file not present");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ(BOGUS_STR));
|
2018-04-29 10:16:59 -04:00
|
|
|
TEST_ERROR(
|
2018-04-30 17:27:39 -04:00
|
|
|
archiveAsyncStatus(archiveModePush, segment, false), FormatError,
|
|
|
|
"000000010000000100000001.ok content must have at least two lines");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ(BOGUS_STR "\n"));
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_ERROR(
|
|
|
|
archiveAsyncStatus(archiveModePush, segment, false), FormatError, "000000010000000100000001.ok message must be > 0");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ(BOGUS_STR "\nmessage"));
|
2018-05-18 11:57:32 -04:00
|
|
|
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, false), FormatError, "unable to convert string 'BOGUS' to int");
|
2018-04-30 17:27:39 -04:00
|
|
|
|
2018-09-16 14:12:53 -04:00
|
|
|
storagePutNP(storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), NULL);
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ("0\nwarning"));
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file with warning");
|
2018-07-20 18:51:42 -04:00
|
|
|
harnessLogResult("P00 WARN: warning");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ("25\nerror"));
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "error status renamed to ok");
|
2018-07-20 18:51:42 -04:00
|
|
|
harnessLogResult(
|
2018-04-29 10:16:59 -04:00
|
|
|
"P00 WARN: WAL segment '000000010000000100000001' was not pushed due to error [25] and was manually skipped: error");
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
storagePutNP(
|
2018-09-26 18:46:52 +01:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))), bufNew(0));
|
2018-04-29 10:16:59 -04:00
|
|
|
TEST_ERROR(
|
2018-04-30 17:27:39 -04:00
|
|
|
archiveAsyncStatus(archiveModePush, segment, false), AssertError,
|
2018-04-29 10:16:59 -04:00
|
|
|
strPtr(
|
|
|
|
strNewFmt(
|
|
|
|
"multiple status files found in '%s/archive/db/out' for WAL segment '000000010000000100000001'", testPath())));
|
|
|
|
|
|
|
|
unlink(strPtr(storagePathNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment)))));
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_ERROR(
|
|
|
|
archiveAsyncStatus(archiveModePush, segment, true), AssertError,
|
|
|
|
"status file '000000010000000100000001.error' has no content");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
|
|
|
storagePutNP(
|
2018-09-16 14:12:53 -04:00
|
|
|
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.error", strPtr(segment))),
|
2018-09-26 18:46:52 +01:00
|
|
|
bufNewZ("25\nmessage"));
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, true), AssertError, "message");
|
2018-04-29 10:16:59 -04:00
|
|
|
|
2018-04-30 17:27:39 -04:00
|
|
|
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), false, "suppress error");
|
2018-04-29 10:16:59 -04:00
|
|
|
}
|
2018-04-29 11:47:50 -04:00
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
2018-09-07 08:00:18 -07:00
|
|
|
if (testBegin("walIsPartial()"))
|
|
|
|
{
|
|
|
|
TEST_RESULT_BOOL(walIsPartial(strNew("000000010000000100000001")), false, "not partial");
|
|
|
|
TEST_RESULT_BOOL(walIsPartial(strNew("FFFFFFFFFFFFFFFFFFFFFFFF.partial")), true, "partial");
|
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("walIsSegment()"))
|
|
|
|
{
|
|
|
|
TEST_RESULT_BOOL(walIsSegment(strNew("000000010000000100000001")), true, "wal segment");
|
|
|
|
TEST_RESULT_BOOL(walIsSegment(strNew("FFFFFFFFFFFFFFFFFFFFFFFF.partial")), true, "partial wal segment");
|
|
|
|
TEST_RESULT_BOOL(walIsSegment(strNew("0000001A.history")), false, "history file");
|
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("walSegmentFind()"))
|
|
|
|
{
|
|
|
|
// Load configuration to set repo-path and stanza
|
|
|
|
StringList *argList = strLstNew();
|
|
|
|
strLstAddZ(argList, "pgbackrest");
|
|
|
|
strLstAddZ(argList, "--stanza=db");
|
|
|
|
strLstAdd(argList, strNewFmt("--repo-path=%s", testPath()));
|
|
|
|
strLstAddZ(argList, "archive-get");
|
|
|
|
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
|
|
|
|
|
|
|
TEST_RESULT_PTR(walSegmentFind(storageRepo(), strNew("9.6-2"), strNew("123456781234567812345678")), NULL, "no path");
|
|
|
|
|
|
|
|
storagePathCreateNP(storageTest, strNew("archive/db/9.6-2/1234567812345678"));
|
|
|
|
TEST_RESULT_PTR(walSegmentFind(storageRepo(), strNew("9.6-2"), strNew("123456781234567812345678")), NULL, "no segment");
|
|
|
|
|
|
|
|
storagePutNP(
|
|
|
|
storageNewWriteNP(
|
|
|
|
storageTest,
|
|
|
|
strNew("archive/db/9.6-2/1234567812345678/123456781234567812345678-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentFind(storageRepo(), strNew("9.6-2"), strNew("123456781234567812345678"))),
|
|
|
|
"123456781234567812345678-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "found segment");
|
|
|
|
|
|
|
|
storagePutNP(
|
|
|
|
storageNewWriteNP(
|
|
|
|
storageTest,
|
|
|
|
strNew("archive/db/9.6-2/1234567812345678/123456781234567812345678-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.gz")),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
TEST_ERROR(
|
|
|
|
walSegmentFind(storageRepo(), strNew("9.6-2"), strNew("123456781234567812345678")),
|
|
|
|
ArchiveDuplicateError,
|
|
|
|
"duplicates found in archive for WAL segment 123456781234567812345678:"
|
|
|
|
" 123456781234567812345678-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
", 123456781234567812345678-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.gz"
|
|
|
|
"\nHINT: are multiple primaries archiving to this stanza?");
|
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
2018-04-29 11:47:50 -04:00
|
|
|
if (testBegin("walSegmentNext()"))
|
|
|
|
{
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("000000010000000100000001"), 16 * 1024 * 1024, PG_VERSION_10)),
|
|
|
|
"000000010000000100000002", "get next");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("0000000100000001000000FE"), 16 * 1024 * 1024, PG_VERSION_93)),
|
|
|
|
"0000000100000001000000FF", "get next");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("0000009900000001000000FF"), 16 * 1024 * 1024, PG_VERSION_93)),
|
|
|
|
"000000990000000200000000", "get next overflow >= 9.3");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("0000000100000001000000FE"), 16 * 1024 * 1024, PG_VERSION_92)),
|
|
|
|
"000000010000000200000000", "get next overflow < 9.3");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("000000010000000100000003"), 1024 * 1024 * 1024, PG_VERSION_11)),
|
|
|
|
"000000010000000200000000", "get next overflow >= 11/1GB");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(walSegmentNext(strNew("000000010000006700000FFF"), 1024 * 1024, PG_VERSION_11)),
|
|
|
|
"000000010000006800000000", "get next overflow >= 11/1MB");
|
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("walSegmentRange()"))
|
|
|
|
{
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(strLstJoin(walSegmentRange(strNew("000000010000000100000000"), 16 * 1024 * 1024, PG_VERSION_92, 1), "|")),
|
|
|
|
"000000010000000100000000", "get single");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(strLstJoin(walSegmentRange(strNew("0000000100000001000000FD"), 16 * 1024 * 1024, PG_VERSION_92, 4), "|")),
|
|
|
|
"0000000100000001000000FD|0000000100000001000000FE|000000010000000200000000|000000010000000200000001",
|
|
|
|
"get range < 9.3");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(strLstJoin(walSegmentRange(strNew("0000000100000001000000FD"), 16 * 1024 * 1024, PG_VERSION_93, 4), "|")),
|
|
|
|
"0000000100000001000000FD|0000000100000001000000FE|0000000100000001000000FF|000000010000000200000000",
|
|
|
|
"get range >= 9.3");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(strLstJoin(walSegmentRange(strNew("000000080000000A00000000"), 1024 * 1024 * 1024, PG_VERSION_11, 8), "|")),
|
|
|
|
"000000080000000A00000000|000000080000000A00000001|000000080000000A00000002|000000080000000A00000003|"
|
|
|
|
"000000080000000B00000000|000000080000000B00000001|000000080000000B00000002|000000080000000B00000003",
|
|
|
|
"get range >= 11/1GB");
|
|
|
|
TEST_RESULT_STR(
|
|
|
|
strPtr(strLstJoin(walSegmentRange(strNew("000000070000000700000FFE"), 1024 * 1024, PG_VERSION_11, 4), "|")),
|
|
|
|
"000000070000000700000FFE|000000070000000700000FFF|000000070000000800000000|000000070000000800000001",
|
|
|
|
"get range >= 11/1MB");
|
|
|
|
}
|
2018-05-18 11:57:32 -04:00
|
|
|
|
|
|
|
FUNCTION_HARNESS_RESULT_VOID();
|
2018-04-29 10:16:59 -04:00
|
|
|
}
|