mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Refactor of pq shim to allow more flexible scripting.
The pq scripts were pretty static which had already led to a lot of code duplication in the backup test harness. Instead allow the scripts to be built dynamically, which allows for much more flexibility and reduces duplication. For now just make these changes in the backup harness, but they may be useful elsewhere. While we are making big changes, also update the macro/function names to hew closer to our current harness naming conventions.
This commit is contained in:
parent
306fdff93a
commit
e0f5880b09
@ -509,17 +509,13 @@ HRN_FORK_END();
|
||||
A PostgreSQL libpq shim is provided to simulate interactions with PostgreSQL. Below is a simple example. See [harnessPq.h](https://github.com/pgbackrest/pgbackrest/blob/main/test/src/common/harnessPq.h) for more details.
|
||||
```
|
||||
// Set up two standbys but no primary
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
|
||||
// Close the "inner" session first (8) then the outer (1)
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
||||
```
|
||||
|
@ -571,17 +571,13 @@ HRN_FORK_END();
|
||||
|
||||
<code-block>
|
||||
// Set up two standbys but no primary
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
|
||||
// Close the "inner" session first (8) then the outer (1)
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
||||
</code-block>
|
||||
|
@ -48,305 +48,186 @@ hrnCmdBackup(void)
|
||||
void
|
||||
hrnBackupPqScript(const unsigned int pgVersion, const time_t backupTimeStart, HrnBackupPqScriptParam param)
|
||||
{
|
||||
const char *const pg1Path = zNewFmt("%s/pg1", testPath());
|
||||
const char *const pg2Path = zNewFmt("%s/pg2", testPath());
|
||||
|
||||
// If no timeline specified then use timeline 1
|
||||
param.timeline = param.timeline == 0 ? 1 : param.timeline;
|
||||
|
||||
// Read pg_control to get info about the cluster
|
||||
PgControl pgControl = pgControlFromFile(storagePg(), param.pgVersionForce);
|
||||
|
||||
// Set archive timeout really small to save time on errors
|
||||
cfgOptionSet(cfgOptArchiveTimeout, cfgSourceParam, varNewInt64(100));
|
||||
|
||||
// Set LSN and WAL start/stop
|
||||
uint64_t lsnStart = ((uint64_t)backupTimeStart & 0xFFFFFF00) << 28;
|
||||
uint64_t lsnStop =
|
||||
lsnStart + ((uint64_t)(param.walTotal == 0 ? 0 : param.walTotal - 1) * (uint64_t)pgControl.walSegmentSize) +
|
||||
(uint64_t)(pgControl.walSegmentSize / 2);
|
||||
|
||||
const char *walSegmentPrior = strZ(
|
||||
pgLsnToWalSegment(param.timeline, lsnStart - pgControl.walSegmentSize, pgControl.walSegmentSize));
|
||||
const char *lsnStartStr = strZ(pgLsnToStr(lsnStart));
|
||||
const char *walSegmentStart = strZ(pgLsnToWalSegment(param.timeline, lsnStart, pgControl.walSegmentSize));
|
||||
const char *lsnStopStr = strZ(pgLsnToStr(lsnStop));
|
||||
const char *walSegmentStop = strZ(pgLsnToWalSegment(param.timeline, lsnStop, pgControl.walSegmentSize));
|
||||
|
||||
// Save pg_control with updated info
|
||||
pgControl.checkpoint = lsnStart;
|
||||
pgControl.timeline = param.timeline;
|
||||
|
||||
HRN_STORAGE_PUT(
|
||||
storagePgIdxWrite(0), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, hrnPgControlToBuffer(0, 0, pgControl),
|
||||
.timeModified = backupTimeStart);
|
||||
|
||||
// Update pg_control on primary with the backup time
|
||||
HRN_PG_CONTROL_TIME(storagePgIdxWrite(0), backupTimeStart);
|
||||
|
||||
// Write WAL segments to the archive
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (!param.noPriorWal)
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
InfoArchive *infoArchive = infoArchiveLoadFile(
|
||||
storageRepo(), INFO_ARCHIVE_PATH_FILE_STR, param.cipherType == 0 ? cipherTypeNone : param.cipherType,
|
||||
param.cipherPass == NULL ? NULL : STR(param.cipherPass));
|
||||
const String *archiveId = infoArchiveId(infoArchive);
|
||||
StringList *walSegmentList = pgLsnRangeToWalSegmentList(
|
||||
param.timeline, lsnStart - pgControl.walSegmentSize, param.noWal ? lsnStart - pgControl.walSegmentSize : lsnStop,
|
||||
pgControl.walSegmentSize);
|
||||
const char *const pg1Path = zNewFmt("%s/pg1", testPath());
|
||||
const char *const pg2Path = zNewFmt("%s/pg2", testPath());
|
||||
|
||||
Buffer *walBuffer = bufNew((size_t)pgControl.walSegmentSize);
|
||||
bufUsedSet(walBuffer, bufSize(walBuffer));
|
||||
memset(bufPtr(walBuffer), 0, bufSize(walBuffer));
|
||||
HRN_PG_WAL_TO_BUFFER(walBuffer, pgControl.version, .systemId = pgControl.systemId);
|
||||
const String *walChecksum = strNewEncode(encodingHex, cryptoHashOne(hashTypeSha1, walBuffer));
|
||||
// If no timeline specified then use timeline 1
|
||||
param.timeline = param.timeline == 0 ? 1 : param.timeline;
|
||||
|
||||
for (unsigned int walSegmentIdx = 0; walSegmentIdx < strLstSize(walSegmentList); walSegmentIdx++)
|
||||
{
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
StorageWrite *write = storageNewWriteP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(
|
||||
STORAGE_REPO_ARCHIVE "/%s/%s-%s%s", strZ(archiveId), strZ(strLstGet(walSegmentList, walSegmentIdx)),
|
||||
strZ(walChecksum), strZ(compressExtStr(param.walCompressType))));
|
||||
// Read pg_control to get info about the cluster
|
||||
PgControl pgControl = pgControlFromFile(storagePg(), param.pgVersionForce);
|
||||
|
||||
if (param.walCompressType != compressTypeNone)
|
||||
ioFilterGroupAdd(ioWriteFilterGroup(storageWriteIo(write)), compressFilterP(param.walCompressType, 1));
|
||||
// Set archive timeout really small to save time on errors
|
||||
cfgOptionSet(cfgOptArchiveTimeout, cfgSourceParam, varNewInt64(100));
|
||||
|
||||
storagePutP(write, walBuffer);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
}
|
||||
// Set LSN and WAL start/stop
|
||||
uint64_t lsnStart = ((uint64_t)backupTimeStart & 0xFFFFFF00) << 28;
|
||||
uint64_t lsnStop =
|
||||
lsnStart + ((uint64_t)(param.walTotal == 0 ? 0 : param.walTotal - 1) * (uint64_t)pgControl.walSegmentSize) +
|
||||
(uint64_t)(pgControl.walSegmentSize / 2);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (pgVersion == PG_VERSION_95)
|
||||
{
|
||||
ASSERT(!param.backupStandby);
|
||||
ASSERT(!param.errorAfterStart);
|
||||
|
||||
if (param.noArchiveCheck)
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, pg1Path, false, NULL, NULL),
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
|
||||
HRNPQ_MACRO_START_BACKUP_LE_95(1, param.startFast, lsnStartStr, walSegmentStart),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
|
||||
|
||||
// Get copy start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000),
|
||||
|
||||
// Ping
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, lsnStopStr, walSegmentStop),
|
||||
|
||||
// Get stop time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 52427000),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, pg1Path, false, NULL, NULL),
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, walSegmentPrior),
|
||||
HRNPQ_MACRO_START_BACKUP_LE_95(1, param.startFast, lsnStartStr, walSegmentStart),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
|
||||
|
||||
// Get copy start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000),
|
||||
|
||||
// Ping
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, lsnStopStr, walSegmentStop),
|
||||
|
||||
// Get stop time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 2000),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
else if (pgVersion == PG_VERSION_96)
|
||||
{
|
||||
ASSERT(param.backupStandby);
|
||||
ASSERT(!param.errorAfterStart);
|
||||
ASSERT(!param.noArchiveCheck);
|
||||
const char *walSegmentPrior = strZ(
|
||||
pgLsnToWalSegment(param.timeline, lsnStart - pgControl.walSegmentSize, pgControl.walSegmentSize));
|
||||
const char *lsnStartStr = strZ(pgLsnToStr(lsnStart));
|
||||
const char *walSegmentStart = strZ(pgLsnToWalSegment(param.timeline, lsnStart, pgControl.walSegmentSize));
|
||||
const char *lsnStopStr = strZ(pgLsnToStr(lsnStop));
|
||||
const char *walSegmentStop = strZ(pgLsnToWalSegment(param.timeline, lsnStop, pgControl.walSegmentSize));
|
||||
|
||||
// Save pg_control with updated info
|
||||
HRN_STORAGE_PUT(storagePgIdxWrite(1), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, hrnPgControlToBuffer(0, 0, pgControl));
|
||||
pgControl.checkpoint = lsnStart;
|
||||
pgControl.timeline = param.timeline;
|
||||
|
||||
if (param.noPriorWal)
|
||||
HRN_STORAGE_PUT(
|
||||
storagePgIdxWrite(0), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, hrnPgControlToBuffer(0, 0, pgControl),
|
||||
.timeModified = backupTimeStart);
|
||||
|
||||
// Update pg_control on primary with the backup time
|
||||
HRN_PG_CONTROL_TIME(storagePgIdxWrite(0), backupTimeStart);
|
||||
|
||||
// Write WAL segments to the archive
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
if (!param.noPriorWal)
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
InfoArchive *infoArchive = infoArchiveLoadFile(
|
||||
storageRepo(), INFO_ARCHIVE_PATH_FILE_STR, param.cipherType == 0 ? cipherTypeNone : param.cipherType,
|
||||
param.cipherPass == NULL ? NULL : STR(param.cipherPass));
|
||||
const String *archiveId = infoArchiveId(infoArchive);
|
||||
StringList *walSegmentList = pgLsnRangeToWalSegmentList(
|
||||
param.timeline, lsnStart - pgControl.walSegmentSize, param.noWal ? lsnStart - pgControl.walSegmentSize : lsnStop,
|
||||
pgControl.walSegmentSize);
|
||||
|
||||
Buffer *walBuffer = bufNew((size_t)pgControl.walSegmentSize);
|
||||
bufUsedSet(walBuffer, bufSize(walBuffer));
|
||||
memset(bufPtr(walBuffer), 0, bufSize(walBuffer));
|
||||
HRN_PG_WAL_TO_BUFFER(walBuffer, pgControl.version, .systemId = pgControl.systemId);
|
||||
const String *walChecksum = strNewEncode(encodingHex, cryptoHashOne(hashTypeSha1, walBuffer));
|
||||
|
||||
for (unsigned int walSegmentIdx = 0; walSegmentIdx < strLstSize(walSegmentList); walSegmentIdx++)
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, pg1Path, false, NULL, NULL),
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
StorageWrite *write = storageNewWriteP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(
|
||||
STORAGE_REPO_ARCHIVE "/%s/%s-%s%s", strZ(archiveId), strZ(strLstGet(walSegmentList, walSegmentIdx)),
|
||||
strZ(walChecksum), strZ(compressExtStr(param.walCompressType))));
|
||||
|
||||
// Connect to standby
|
||||
HRNPQ_MACRO_OPEN_GE_96(2, "dbname='postgres' port=5433", PG_VERSION_96, pg2Path, true, NULL, NULL),
|
||||
if (param.walCompressType != compressTypeNone)
|
||||
ioFilterGroupAdd(ioWriteFilterGroup(storageWriteIo(write)), compressFilterP(param.walCompressType, 1));
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, walSegmentPrior),
|
||||
HRNPQ_MACRO_START_BACKUP_96(1, true, lsnStartStr, walSegmentStart),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
|
||||
|
||||
// Wait for standby to sync
|
||||
HRNPQ_MACRO_REPLAY_WAIT_96(2, lsnStartStr),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
storagePutP(write, walBuffer);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
}
|
||||
|
||||
// Generate pq script
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
// Connect to primary
|
||||
if (pgVersion <= PG_VERSION_95)
|
||||
HRN_PQ_SCRIPT_SET(HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", pgVersion, pg1Path, false, NULL, NULL));
|
||||
else
|
||||
HRN_PQ_SCRIPT_SET(HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", pgVersion, pg1Path, false, NULL, NULL));
|
||||
|
||||
// Connect to standby
|
||||
if (param.backupStandby)
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
// Save standby pg_control with updated info
|
||||
HRN_STORAGE_PUT(storagePgIdxWrite(1), PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, hrnPgControlToBuffer(0, 0, pgControl));
|
||||
|
||||
if (pgVersion <= PG_VERSION_95)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_OPEN_GE_93(2, "dbname='postgres' port=5433", pgVersion, pg2Path, true, NULL, NULL));
|
||||
else
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_OPEN_GE_96(2, "dbname='postgres' port=5433", pgVersion, pg2Path, true, NULL, NULL));
|
||||
}
|
||||
|
||||
// Get start time
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_TIME_QUERY(1, (int64_t)backupTimeStart * 1000));
|
||||
|
||||
// Advisory lock
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true));
|
||||
|
||||
// Check if backup is in progress (only for exclusive backup)
|
||||
if (pgVersion <= PG_VERSION_95)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_IS_IN_BACKUP(1, false));
|
||||
|
||||
// Perform archive check
|
||||
if (!param.noArchiveCheck)
|
||||
{
|
||||
const char *const walSegment = param.walSwitch ? walSegmentStart : walSegmentPrior;
|
||||
|
||||
if (pgVersion <= PG_VERSION_96)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_CURRENT_WAL_LE_96(1, walSegment));
|
||||
else
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_CURRENT_WAL_GE_10(1, walSegment));
|
||||
}
|
||||
|
||||
// Start backup
|
||||
if (pgVersion <= PG_VERSION_95)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_START_BACKUP_LE_95(1, param.startFast, lsnStartStr, walSegmentStart));
|
||||
else if (pgVersion <= PG_VERSION_96)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_START_BACKUP_96(1, param.startFast, lsnStartStr, walSegmentStart));
|
||||
else
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_START_BACKUP_GE_10(1, param.startFast, lsnStartStr, walSegmentStart));
|
||||
|
||||
// Switch WAL segment so it can be checked
|
||||
if (param.walSwitch)
|
||||
{
|
||||
HRN_PQ_SCRIPT_ADD(
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(1, "X/X"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(1, "wal", walSegmentStart));
|
||||
}
|
||||
|
||||
// Get database list
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_DATABASE_LIST_1(1, "test1"));
|
||||
|
||||
// Get tablespace list
|
||||
if (param.tablespace)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_TABLESPACE_LIST_1(1, 32768, "tblspc32768"));
|
||||
else
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_TABLESPACE_LIST_0(1));
|
||||
|
||||
// Wait for standby to sync
|
||||
if (param.backupStandby)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_REPLAY_WAIT_96(2, lsnStartStr));
|
||||
|
||||
// Continue if WAL check succeeds
|
||||
if (!param.noPriorWal)
|
||||
{
|
||||
// Get copy start time
|
||||
HRN_PQ_SCRIPT_ADD(
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000));
|
||||
|
||||
// Continue if there is no error after start
|
||||
if (!param.errorAfterStart)
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, pg1Path, false, NULL, NULL),
|
||||
// Ping to check standby mode
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false));
|
||||
|
||||
// Connect to standby
|
||||
HRNPQ_MACRO_OPEN_GE_96(2, "dbname='postgres' port=5433", PG_VERSION_96, pg2Path, true, NULL, NULL),
|
||||
if (param.backupStandby)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, true));
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false));
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, walSegmentPrior),
|
||||
HRNPQ_MACRO_START_BACKUP_96(1, true, lsnStartStr, walSegmentStart),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
|
||||
|
||||
// Wait for standby to sync
|
||||
HRNPQ_MACRO_REPLAY_WAIT_96(2, lsnStartStr),
|
||||
|
||||
// Get copy start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000),
|
||||
|
||||
// Ping
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, true),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, true),
|
||||
if (param.backupStandby)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, true));
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_96(1, lsnStopStr, walSegmentStop, false),
|
||||
if (pgVersion <= PG_VERSION_95)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_STOP_BACKUP_LE_95(1, lsnStopStr, walSegmentStop));
|
||||
else if (pgVersion <= PG_VERSION_96)
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_STOP_BACKUP_96(1, lsnStopStr, walSegmentStop, false));
|
||||
else
|
||||
HRN_PQ_SCRIPT_ADD(HRN_PQ_SCRIPT_STOP_BACKUP_GE_10(1, lsnStopStr, walSegmentStop, true));
|
||||
|
||||
// Get stop time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 2000),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_ADD(
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, ((int64_t)backupTimeStart + (param.noArchiveCheck ? 52427 : 2)) * 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
else if (pgVersion == PG_VERSION_11)
|
||||
{
|
||||
ASSERT(!param.backupStandby);
|
||||
ASSERT(!param.noArchiveCheck);
|
||||
|
||||
if (param.errorAfterStart)
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, pg1Path, false, NULL, NULL),
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_GE_10(1, walSegmentPrior),
|
||||
HRNPQ_MACRO_START_BACKUP_GE_10(1, param.startFast, lsnStartStr, walSegmentStart),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_1(1, 32768, "tblspc32768"),
|
||||
|
||||
// Get copy start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, pg1Path, false, NULL, NULL),
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_GE_10(1, walSegmentStart),
|
||||
HRNPQ_MACRO_START_BACKUP_GE_10(1, param.startFast, lsnStartStr, walSegmentStart),
|
||||
|
||||
// Switch WAL segment so it can be checked
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "X/X"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(1, "wal", walSegmentStart),
|
||||
|
||||
// Get database and tablespace list
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_1(1, 32768, "tblspc32768"),
|
||||
|
||||
// Get copy start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 1000),
|
||||
|
||||
// Ping
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_GE_10(1, lsnStopStr, walSegmentStop, true),
|
||||
|
||||
// Get stop time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, (int64_t)backupTimeStart * 1000 + 2000),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_FMT(AssertError, "unsupported test version %u", pgVersion); // {uncoverable - no invalid versions in tests}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ typedef struct HrnBackupPqScriptParam
|
||||
bool noWal; // Don't write test WAL segments
|
||||
bool noPriorWal; // Don't write prior test WAL segments
|
||||
bool noArchiveCheck; // Do not check archive
|
||||
bool walSwitch; // WAL switch is required
|
||||
bool tablespace; // Is there a tablespace?
|
||||
CompressType walCompressType; // Compress type for the archive files
|
||||
CipherType cipherType; // Cipher type
|
||||
const char *cipherPass; // Cipher pass
|
||||
|
@ -22,62 +22,93 @@ Pq shim error prefix
|
||||
#define PQ_ERROR_PREFIX "PQ SHIM ERROR"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Script that defines how shim functions operate
|
||||
Local variables
|
||||
***********************************************************************************************************************************/
|
||||
HarnessPq harnessPqScript[1024];
|
||||
bool harnessPqScriptDone = true;
|
||||
unsigned int harnessPqScriptIdx;
|
||||
|
||||
// Is PQfinish scripting required?
|
||||
bool harnessPqStrict = false;
|
||||
|
||||
// If there is a script failure change the behavior of cleanup functions to return immediately so the real error will be reported
|
||||
// rather than a bogus scripting error during cleanup
|
||||
bool harnessPqScriptFail;
|
||||
char harnessPqScriptError[4096];
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Set pq script
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
harnessPqScriptSet(HarnessPq *harnessPqScriptParam)
|
||||
static struct HrnPqLocal
|
||||
{
|
||||
if (!harnessPqScriptDone)
|
||||
MemContext *memContext; // Script mem context
|
||||
|
||||
// Script that defines how shim functions operate
|
||||
HrnPqScript script[1024];
|
||||
unsigned int scriptSize;
|
||||
unsigned int scriptIdx;
|
||||
|
||||
// Is PQfinish scripting required?
|
||||
bool strict;
|
||||
|
||||
// If there is a script failure change the behavior of cleanup functions to return immediately so the real error will be
|
||||
// reported rather than a bogus scripting error during cleanup
|
||||
bool scriptFail;
|
||||
char scriptError[4096];
|
||||
} hrnPqLocal;
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
hrnPqScriptSet(const HrnPqScript *const script, const unsigned int scriptSize)
|
||||
{
|
||||
if (hrnPqLocal.scriptSize != 0)
|
||||
THROW(AssertError, "previous pq script has not yet completed");
|
||||
|
||||
if (harnessPqScriptParam[0].function == NULL)
|
||||
THROW(AssertError, "pq script must have entries");
|
||||
|
||||
// Copy records into local storage
|
||||
unsigned int copyIdx = 0;
|
||||
|
||||
while (harnessPqScriptParam[copyIdx].function != NULL)
|
||||
{
|
||||
harnessPqScript[copyIdx] = harnessPqScriptParam[copyIdx];
|
||||
copyIdx++;
|
||||
}
|
||||
|
||||
harnessPqScript[copyIdx].function = NULL;
|
||||
harnessPqScriptDone = false;
|
||||
harnessPqScriptIdx = 0;
|
||||
hrnPqScriptAdd(script, scriptSize);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
harnessPqScriptStrictSet(bool strict)
|
||||
hrnPqScriptAdd(const HrnPqScript *const script, const unsigned int scriptSize)
|
||||
{
|
||||
harnessPqStrict = strict;
|
||||
if (scriptSize == 0)
|
||||
THROW(AssertError, "pq script must have entries");
|
||||
|
||||
if (hrnPqLocal.scriptSize == 0)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(memContextTop())
|
||||
{
|
||||
MEM_CONTEXT_NEW_BEGIN(HrnPqLocal, .childQty = MEM_CONTEXT_QTY_MAX)
|
||||
{
|
||||
hrnPqLocal.memContext = MEM_CONTEXT_NEW();
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
hrnPqLocal.scriptIdx = 0;
|
||||
}
|
||||
|
||||
// Copy records into local storage
|
||||
MEM_CONTEXT_BEGIN(hrnPqLocal.memContext)
|
||||
{
|
||||
for (unsigned int scriptIdx = 0; scriptIdx < scriptSize; scriptIdx++)
|
||||
{
|
||||
hrnPqLocal.script[hrnPqLocal.scriptSize] = script[scriptIdx];
|
||||
|
||||
if (script[scriptIdx].param != NULL)
|
||||
hrnPqLocal.script[hrnPqLocal.scriptSize].param = strZ(strNewZ(script[scriptIdx].param));
|
||||
|
||||
if (script[scriptIdx].resultZ != NULL)
|
||||
hrnPqLocal.script[hrnPqLocal.scriptSize].resultZ = strZ(strNewZ(script[scriptIdx].resultZ));
|
||||
|
||||
hrnPqLocal.scriptSize++;
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
hrnPqScriptStrictSet(bool strict)
|
||||
{
|
||||
hrnPqLocal.strict = strict;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Run pq script
|
||||
***********************************************************************************************************************************/
|
||||
static HarnessPq *
|
||||
harnessPqScriptRun(const char *const function, const VariantList *const param, const HarnessPq *const parent)
|
||||
static HrnPqScript *
|
||||
hrnPqScriptRun(const char *const function, const VariantList *const param, const HrnPqScript *const parent)
|
||||
{
|
||||
// If an error has already been thrown then throw the same error again
|
||||
if (harnessPqScriptFail)
|
||||
THROW(AssertError, harnessPqScriptError);
|
||||
if (hrnPqLocal.scriptFail)
|
||||
THROW(AssertError, hrnPqLocal.scriptError);
|
||||
|
||||
// Convert params to json for comparison and reporting
|
||||
String *paramStr = NULL;
|
||||
@ -93,36 +124,37 @@ harnessPqScriptRun(const char *const function, const VariantList *const param, c
|
||||
paramStr = strNew();
|
||||
|
||||
// Ensure script has not ended
|
||||
if (harnessPqScriptDone)
|
||||
if (hrnPqLocal.scriptSize == 0)
|
||||
{
|
||||
snprintf(harnessPqScriptError, sizeof(harnessPqScriptError), "pq script ended before %s (%s)", function, strZ(paramStr));
|
||||
snprintf(
|
||||
hrnPqLocal.scriptError, sizeof(hrnPqLocal.scriptError), "pq script ended before %s (%s)", function, strZ(paramStr));
|
||||
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", harnessPqScriptError);
|
||||
harnessPqScriptFail = true;
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", hrnPqLocal.scriptError);
|
||||
hrnPqLocal.scriptFail = true;
|
||||
|
||||
THROW(AssertError, harnessPqScriptError);
|
||||
THROW(AssertError, hrnPqLocal.scriptError);
|
||||
}
|
||||
|
||||
// Get current script item
|
||||
HarnessPq *result = &harnessPqScript[harnessPqScriptIdx];
|
||||
HrnPqScript *const result = &hrnPqLocal.script[hrnPqLocal.scriptIdx];
|
||||
|
||||
// Check that expected function was called
|
||||
if (strcmp(result->function, function) != 0)
|
||||
{
|
||||
snprintf(
|
||||
harnessPqScriptError, sizeof(harnessPqScriptError), "pq script [%u] expected function %s (%s) but got %s (%s)",
|
||||
harnessPqScriptIdx, result->function, result->param == NULL ? "" : result->param, function, strZ(paramStr));
|
||||
hrnPqLocal.scriptError, sizeof(hrnPqLocal.scriptError), "pq script [%u] expected function %s (%s) but got %s (%s)",
|
||||
hrnPqLocal.scriptIdx, result->function, result->param == NULL ? "" : result->param, function, strZ(paramStr));
|
||||
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", harnessPqScriptError);
|
||||
harnessPqScriptFail = true;
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", hrnPqLocal.scriptError);
|
||||
hrnPqLocal.scriptFail = true;
|
||||
|
||||
// Return without error if closing the connection and an error is currently being thrown. Errors outside of the pq shim can
|
||||
// cause the connection to be cleaned up and we don't want to mask those errors. However, the failure is still logged and
|
||||
// any subsequent call to the pq shim will result in an error.
|
||||
if (strcmp(function, HRNPQ_FINISH) == 0 && errorType() != NULL)
|
||||
if (strcmp(function, HRN_PQ_FINISH) == 0 && errorType() != NULL)
|
||||
return NULL;
|
||||
|
||||
THROW(AssertError, harnessPqScriptError);
|
||||
THROW(AssertError, hrnPqLocal.scriptError);
|
||||
}
|
||||
|
||||
// Check that parameters match
|
||||
@ -130,38 +162,42 @@ harnessPqScriptRun(const char *const function, const VariantList *const param, c
|
||||
(param != NULL && result->param != NULL && !strEqZ(paramStr, result->param)))
|
||||
{
|
||||
snprintf(
|
||||
harnessPqScriptError, sizeof(harnessPqScriptError), "pq script [%u] function '%s', expects param '%s' but got '%s'",
|
||||
harnessPqScriptIdx, result->function, result->param ? result->param : "NULL", param ? strZ(paramStr) : "NULL");
|
||||
hrnPqLocal.scriptError, sizeof(hrnPqLocal.scriptError), "pq script [%u] function '%s', expects param '%s' but got '%s'",
|
||||
hrnPqLocal.scriptIdx, result->function, result->param ? result->param : "NULL", param ? strZ(paramStr) : "NULL");
|
||||
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", harnessPqScriptError);
|
||||
harnessPqScriptFail = true;
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", hrnPqLocal.scriptError);
|
||||
hrnPqLocal.scriptFail = true;
|
||||
|
||||
THROW(AssertError, harnessPqScriptError);
|
||||
THROW(AssertError, hrnPqLocal.scriptError);
|
||||
}
|
||||
|
||||
// Make sure the session matches with the parent as a sanity check
|
||||
if (parent != NULL && result->session != parent->session)
|
||||
{
|
||||
snprintf(
|
||||
harnessPqScriptError, sizeof(harnessPqScriptError), "pq script [%u] function '%s', expects session '%u' but got '%u'",
|
||||
harnessPqScriptIdx, result->function, result->session, parent->session);
|
||||
hrnPqLocal.scriptError, sizeof(hrnPqLocal.scriptError),
|
||||
"pq script [%u] function '%s', expects session '%u' but got '%u'", hrnPqLocal.scriptIdx, result->function,
|
||||
result->session, parent->session);
|
||||
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", harnessPqScriptError);
|
||||
harnessPqScriptFail = true;
|
||||
TEST_LOG_FMT(PQ_ERROR_PREFIX ": %s", hrnPqLocal.scriptError);
|
||||
hrnPqLocal.scriptFail = true;
|
||||
|
||||
THROW(AssertError, harnessPqScriptError);
|
||||
THROW(AssertError, hrnPqLocal.scriptError);
|
||||
}
|
||||
|
||||
strFree(paramStr);
|
||||
|
||||
// Sleep if requested
|
||||
if (result->sleep > 0)
|
||||
sleepMSec(result->sleep);
|
||||
|
||||
harnessPqScriptIdx++;
|
||||
hrnPqLocal.scriptIdx++;
|
||||
|
||||
if (harnessPqScript[harnessPqScriptIdx].function == NULL)
|
||||
harnessPqScriptDone = true;
|
||||
|
||||
strFree(paramStr);
|
||||
if (hrnPqLocal.scriptIdx == hrnPqLocal.scriptSize)
|
||||
{
|
||||
memContextFree(hrnPqLocal.memContext);
|
||||
hrnPqLocal.scriptSize = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -172,7 +208,7 @@ Shim for PQconnectdb()
|
||||
PGconn *
|
||||
PQconnectdb(const char *conninfo)
|
||||
{
|
||||
return (PGconn *)harnessPqScriptRun(HRNPQ_CONNECTDB, varLstAdd(varLstNew(), varNewStrZ(conninfo)), NULL);
|
||||
return (PGconn *)hrnPqScriptRun(HRN_PQ_CONNECTDB, varLstAdd(varLstNew(), varNewStrZ(conninfo)), NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -181,7 +217,7 @@ Shim for PQstatus()
|
||||
ConnStatusType
|
||||
PQstatus(const PGconn *conn)
|
||||
{
|
||||
return (ConnStatusType)harnessPqScriptRun(HRNPQ_STATUS, NULL, (HarnessPq *)conn)->resultInt;
|
||||
return (ConnStatusType)hrnPqScriptRun(HRN_PQ_STATUS, NULL, (HrnPqScript *)conn)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -190,7 +226,7 @@ Shim for PQerrorMessage()
|
||||
char *
|
||||
PQerrorMessage(const PGconn *conn)
|
||||
{
|
||||
return (char *)harnessPqScriptRun(HRNPQ_ERRORMESSAGE, NULL, (HarnessPq *)conn)->resultZ;
|
||||
return (char *)hrnPqScriptRun(HRN_PQ_ERRORMESSAGE, NULL, (HrnPqScript *)conn)->resultZ;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -212,7 +248,7 @@ Shim for PQsendQuery()
|
||||
int
|
||||
PQsendQuery(PGconn *conn, const char *query)
|
||||
{
|
||||
return harnessPqScriptRun(HRNPQ_SENDQUERY, varLstAdd(varLstNew(), varNewStrZ(query)), (HarnessPq *)conn)->resultInt;
|
||||
return hrnPqScriptRun(HRN_PQ_SENDQUERY, varLstAdd(varLstNew(), varNewStrZ(query)), (HrnPqScript *)conn)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -221,7 +257,7 @@ Shim for PQconsumeInput()
|
||||
int
|
||||
PQconsumeInput(PGconn *conn)
|
||||
{
|
||||
return harnessPqScriptRun(HRNPQ_CONSUMEINPUT, NULL, (HarnessPq *)conn)->resultInt;
|
||||
return hrnPqScriptRun(HRN_PQ_CONSUMEINPUT, NULL, (HrnPqScript *)conn)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -230,7 +266,7 @@ Shim for PQisBusy()
|
||||
int
|
||||
PQisBusy(PGconn *conn)
|
||||
{
|
||||
return harnessPqScriptRun(HRNPQ_ISBUSY, NULL, (HarnessPq *)conn)->resultInt;
|
||||
return hrnPqScriptRun(HRN_PQ_ISBUSY, NULL, (HrnPqScript *)conn)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -239,8 +275,8 @@ Shim for PQgetCancel()
|
||||
PGcancel *
|
||||
PQgetCancel(PGconn *conn)
|
||||
{
|
||||
HarnessPq *harnessPq = harnessPqScriptRun(HRNPQ_GETCANCEL, NULL, (HarnessPq *)conn);
|
||||
return harnessPq->resultNull ? NULL : (PGcancel *)harnessPq;
|
||||
HrnPqScript *const hrnPq = hrnPqScriptRun(HRN_PQ_GETCANCEL, NULL, (HrnPqScript *)conn);
|
||||
return hrnPq->resultNull ? NULL : (PGcancel *)hrnPq;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -249,15 +285,15 @@ Shim for PQcancel()
|
||||
int
|
||||
PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
|
||||
{
|
||||
HarnessPq *harnessPq = harnessPqScriptRun(HRNPQ_CANCEL, NULL, (HarnessPq *)cancel);
|
||||
HrnPqScript *const hrnPq = hrnPqScriptRun(HRN_PQ_CANCEL, NULL, (HrnPqScript *)cancel);
|
||||
|
||||
if (!harnessPq->resultInt)
|
||||
if (!hrnPq->resultInt)
|
||||
{
|
||||
strncpy(errbuf, harnessPq->resultZ, (size_t)errbufsize);
|
||||
strncpy(errbuf, hrnPq->resultZ, (size_t)errbufsize);
|
||||
errbuf[errbufsize - 1] = '\0';
|
||||
}
|
||||
|
||||
return harnessPq->resultInt;
|
||||
return hrnPq->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -266,7 +302,7 @@ Shim for PQfreeCancel()
|
||||
void
|
||||
PQfreeCancel(PGcancel *cancel)
|
||||
{
|
||||
harnessPqScriptRun(HRNPQ_FREECANCEL, NULL, (HarnessPq *)cancel);
|
||||
hrnPqScriptRun(HRN_PQ_FREECANCEL, NULL, (HrnPqScript *)cancel);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -275,10 +311,10 @@ Shim for PQgetResult()
|
||||
PGresult *
|
||||
PQgetResult(PGconn *conn)
|
||||
{
|
||||
if (!harnessPqScriptFail)
|
||||
if (!hrnPqLocal.scriptFail)
|
||||
{
|
||||
HarnessPq *harnessPq = harnessPqScriptRun(HRNPQ_GETRESULT, NULL, (HarnessPq *)conn);
|
||||
return harnessPq->resultNull ? NULL : (PGresult *)harnessPq;
|
||||
HrnPqScript *const hrnPq = hrnPqScriptRun(HRN_PQ_GETRESULT, NULL, (HrnPqScript *)conn);
|
||||
return hrnPq->resultNull ? NULL : (PGresult *)hrnPq;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -290,7 +326,7 @@ Shim for PQresultStatus()
|
||||
ExecStatusType
|
||||
PQresultStatus(const PGresult *res)
|
||||
{
|
||||
return (ExecStatusType)harnessPqScriptRun(HRNPQ_RESULTSTATUS, NULL, (HarnessPq *)res)->resultInt;
|
||||
return (ExecStatusType)hrnPqScriptRun(HRN_PQ_RESULTSTATUS, NULL, (HrnPqScript *)res)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -299,7 +335,7 @@ Shim for PQresultErrorMessage()
|
||||
char *
|
||||
PQresultErrorMessage(const PGresult *res)
|
||||
{
|
||||
return (char *)harnessPqScriptRun(HRNPQ_RESULTERRORMESSAGE, NULL, (HarnessPq *)res)->resultZ;
|
||||
return (char *)hrnPqScriptRun(HRN_PQ_RESULTERRORMESSAGE, NULL, (HrnPqScript *)res)->resultZ;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -308,7 +344,7 @@ Shim for PQntuples()
|
||||
int
|
||||
PQntuples(const PGresult *res)
|
||||
{
|
||||
return harnessPqScriptRun(HRNPQ_NTUPLES, NULL, (HarnessPq *)res)->resultInt;
|
||||
return hrnPqScriptRun(HRN_PQ_NTUPLES, NULL, (HrnPqScript *)res)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -317,7 +353,7 @@ Shim for PQnfields()
|
||||
int
|
||||
PQnfields(const PGresult *res)
|
||||
{
|
||||
return harnessPqScriptRun(HRNPQ_NFIELDS, NULL, (HarnessPq *)res)->resultInt;
|
||||
return hrnPqScriptRun(HRN_PQ_NFIELDS, NULL, (HrnPqScript *)res)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -326,8 +362,9 @@ Shim for PQgetisnull()
|
||||
int
|
||||
PQgetisnull(const PGresult *res, int tup_num, int field_num)
|
||||
{
|
||||
return harnessPqScriptRun(
|
||||
HRNPQ_GETISNULL, varLstAdd(varLstAdd(varLstNew(), varNewInt(tup_num)), varNewInt(field_num)), (HarnessPq *)res)->resultInt;
|
||||
return hrnPqScriptRun(
|
||||
HRN_PQ_GETISNULL, varLstAdd(varLstAdd(varLstNew(), varNewInt(tup_num)), varNewInt(field_num)),
|
||||
(HrnPqScript *)res)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -336,7 +373,7 @@ Shim for PQftype()
|
||||
Oid
|
||||
PQftype(const PGresult *res, int field_num)
|
||||
{
|
||||
return (Oid)harnessPqScriptRun(HRNPQ_FTYPE, varLstAdd(varLstNew(), varNewInt(field_num)), (HarnessPq *)res)->resultInt;
|
||||
return (Oid)hrnPqScriptRun(HRN_PQ_FTYPE, varLstAdd(varLstNew(), varNewInt(field_num)), (HrnPqScript *)res)->resultInt;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -345,8 +382,8 @@ Shim for PQgetvalue()
|
||||
char *
|
||||
PQgetvalue(const PGresult *res, int tup_num, int field_num)
|
||||
{
|
||||
return (char *)harnessPqScriptRun(
|
||||
HRNPQ_GETVALUE, varLstAdd(varLstAdd(varLstNew(), varNewInt(tup_num)), varNewInt(field_num)), (HarnessPq *)res)->resultZ;
|
||||
return (char *)hrnPqScriptRun(
|
||||
HRN_PQ_GETVALUE, varLstAdd(varLstAdd(varLstNew(), varNewInt(tup_num)), varNewInt(field_num)), (HrnPqScript *)res)->resultZ;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -355,8 +392,8 @@ Shim for PQclear()
|
||||
void
|
||||
PQclear(PGresult *res)
|
||||
{
|
||||
if (!harnessPqScriptFail)
|
||||
harnessPqScriptRun(HRNPQ_CLEAR, NULL, (HarnessPq *)res);
|
||||
if (!hrnPqLocal.scriptFail)
|
||||
hrnPqScriptRun(HRN_PQ_CLEAR, NULL, (HrnPqScript *)res);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -365,8 +402,8 @@ Shim for PQfinish()
|
||||
void
|
||||
PQfinish(PGconn *conn)
|
||||
{
|
||||
if (harnessPqStrict && !harnessPqScriptFail)
|
||||
harnessPqScriptRun(HRNPQ_FINISH, NULL, (HarnessPq *)conn);
|
||||
if (hrnPqLocal.strict && !hrnPqLocal.scriptFail)
|
||||
hrnPqScriptRun(HRN_PQ_FINISH, NULL, (HrnPqScript *)conn);
|
||||
}
|
||||
|
||||
#endif // HARNESS_PQ_REAL
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1949,13 +1949,9 @@ testRun(void)
|
||||
hrnCfgArgRawBool(argList, cfgOptChecksumPage, true);
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL));
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
dbFree(
|
||||
@ -1980,13 +1976,9 @@ testRun(void)
|
||||
hrnCfgArgRawBool(argList, cfgOptChecksumPage, false);
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL));
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
dbFree(
|
||||
@ -1997,13 +1989,9 @@ testRun(void)
|
||||
// Create pg_control without page checksums
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_93);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL));
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
dbFree(
|
||||
@ -2039,24 +2027,20 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptRepoRetentionFull, "1");
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Advance the time slowly to force retries
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392588998),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392588999),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392589001),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392588998),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392588999),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392589001),
|
||||
|
||||
// Stall time to force an error
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392589998),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392589997),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392589998),
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1575392589999),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392589998),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392589997),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392589998),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1575392589999));
|
||||
|
||||
BackupData *backupData = backupInit(
|
||||
infoBackupNew(PG_VERSION_93, HRN_PG_SYSTEMID_93, hrnPgCatalogVersion(PG_VERSION_93), NULL));
|
||||
@ -3076,7 +3060,8 @@ testRun(void)
|
||||
|
||||
// Run backup but error on first archive check
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_96, backupTimeStart, .noPriorWal = true, .backupStandby = true, .walCompressType = compressTypeGz);
|
||||
PG_VERSION_96, backupTimeStart, .noPriorWal = true, .backupStandby = true, .walCompressType = compressTypeGz,
|
||||
.startFast = true);
|
||||
TEST_ERROR(
|
||||
hrnCmdBackup(), ArchiveTimeoutError,
|
||||
"WAL segment 0000000105DA69BF000000FF was not archived before the 100ms timeout\n"
|
||||
@ -3086,7 +3071,8 @@ testRun(void)
|
||||
|
||||
// Run backup but error on archive check
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_96, backupTimeStart, .noWal = true, .backupStandby = true, .walCompressType = compressTypeGz);
|
||||
PG_VERSION_96, backupTimeStart, .noWal = true, .backupStandby = true, .walCompressType = compressTypeGz,
|
||||
.startFast = true);
|
||||
TEST_ERROR(
|
||||
hrnCmdBackup(), ArchiveTimeoutError,
|
||||
"WAL segment 0000000105DA69C000000000 was not archived before the 100ms timeout\n"
|
||||
@ -3106,7 +3092,8 @@ testRun(void)
|
||||
const String *archiveInfoContent = strNewBuf(storageGetP(storageNewReadP(storageRepo(), INFO_ARCHIVE_PATH_FILE_STR)));
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(PG_VERSION_96, backupTimeStart, .backupStandby = true, .walCompressType = compressTypeGz);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_96, backupTimeStart, .backupStandby = true, .walCompressType = compressTypeGz, .startFast = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
// Check archive.info/copy timestamp was updated but contents were not
|
||||
@ -3281,7 +3268,9 @@ testRun(void)
|
||||
((Storage *)storageRepoWrite())->pub.interface.feature ^= 1 << storageFeatureHardLink;
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 3);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 3, .walSwitch = true,
|
||||
.tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
// Reset storage features
|
||||
@ -3407,7 +3396,7 @@ testRun(void)
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
// Preserve prior timestamp on pg_control
|
||||
hrnBackupPqScriptP(PG_VERSION_11, BACKUP_EPOCH + 2300000, .errorAfterStart = true);
|
||||
hrnBackupPqScriptP(PG_VERSION_11, BACKUP_EPOCH + 2300000, .errorAfterStart = true, .tablespace = true);
|
||||
HRN_PG_CONTROL_TIME(storagePg(), backupTimeStart);
|
||||
|
||||
// Run backup
|
||||
@ -3467,7 +3456,8 @@ testRun(void)
|
||||
const char *rel1_3Sha1 = strZ(strNewEncode(encodingHex, cryptoHashOne(hashTypeSha1, relation)));
|
||||
|
||||
// Run backup. Make sure that the timeline selected converts to hexdecimal that can't be interpreted as decimal.
|
||||
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .timeline = 0x2C, .walTotal = 2);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .timeline = 0x2C, .walTotal = 2, .walSwitch = true, .tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -3617,7 +3607,8 @@ testRun(void)
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .pgVersionForce = STRDEF("11"));
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .pgVersionForce = STRDEF("11"),
|
||||
.walSwitch = true, .tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -3747,7 +3738,9 @@ testRun(void)
|
||||
HRN_STORAGE_PUT_EMPTY(storagePgWrite(), "zero", .timeModified = backupTimeStart);
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .walSwitch = true,
|
||||
.tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -3858,7 +3851,9 @@ testRun(void)
|
||||
HRN_STORAGE_PUT(storagePgWrite(), "grow-to-block-incr", file, .timeModified = backupTimeStart);
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .walSwitch = true,
|
||||
.tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -3969,7 +3964,9 @@ testRun(void)
|
||||
HRN_STORAGE_PUT(storagePgWrite(), "grow-to-block-incr", file, .timeModified = backupTimeStart);
|
||||
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2);
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .walSwitch = true,
|
||||
.tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -4093,7 +4090,7 @@ testRun(void)
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeNone, .cipherType = cipherTypeAes256Cbc,
|
||||
.cipherPass = TEST_CIPHER_PASS, .walTotal = 2);
|
||||
.cipherPass = TEST_CIPHER_PASS, .walTotal = 2, .walSwitch = true, .tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
@ -4201,7 +4198,7 @@ testRun(void)
|
||||
// Run backup
|
||||
hrnBackupPqScriptP(
|
||||
PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeNone, .cipherType = cipherTypeAes256Cbc,
|
||||
.cipherPass = TEST_CIPHER_PASS, .walTotal = 2);
|
||||
.cipherPass = TEST_CIPHER_PASS, .walTotal = 2, .walSwitch = true, .tablespace = true);
|
||||
TEST_RESULT_VOID(hrnCmdBackup(), "backup");
|
||||
|
||||
TEST_RESULT_LOG(
|
||||
|
@ -26,7 +26,7 @@ testRun(void)
|
||||
const Storage *const storageTest = storagePosixNewP(TEST_PATH_STR, .write = true);
|
||||
|
||||
// PQfinish() is strictly checked
|
||||
harnessPqScriptStrictSet(true);
|
||||
hrnPqScriptStrictSet(true);
|
||||
|
||||
StringList *argList = strLstNew();
|
||||
|
||||
@ -221,14 +221,11 @@ testRun(void)
|
||||
TEST_TITLE("fail to connect to database");
|
||||
|
||||
// Set up harness to expect a failure to connect to the database
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432\"]"},
|
||||
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRNPQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.function = HRNPQ_FINISH},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432\"]"},
|
||||
{.function = HRN_PQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRN_PQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.function = HRN_PQ_FINISH});
|
||||
|
||||
TEST_ERROR(cmdCheck(), ConfigError, "no database found\nHINT: check indexed pg-path/pg-host configurations");
|
||||
TEST_RESULT_LOG(
|
||||
@ -239,12 +236,9 @@ testRun(void)
|
||||
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_96);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
||||
|
||||
@ -264,16 +258,12 @@ testRun(void)
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(1), PG_VERSION_96);
|
||||
|
||||
// Two standbys found but no primary
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, "/pgdata", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_93(8, "dbname='postgres' port=5433", PG_VERSION_93, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(8, "dbname='postgres' port=5433", PG_VERSION_93, "/pgdata", true, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
||||
|
||||
@ -288,12 +278,9 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptArchiveTimeout, ".5");
|
||||
HRN_CFG_LOAD(cfgCmdCheck, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, "/pgdata", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
// Only confirming we get passed the check for repoIsLocal || more than one pg-path configured
|
||||
TEST_ERROR(
|
||||
@ -314,12 +301,9 @@ testRun(void)
|
||||
HRN_CFG_LOAD(cfgCmdCheck, argList);
|
||||
|
||||
// Primary database connection ok
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
cmdCheck(), FileMissingError,
|
||||
@ -351,16 +335,12 @@ testRun(void)
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_15);
|
||||
|
||||
// Standby database path doesn't match pg_control
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH, true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH, true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
cmdCheck(), DbMismatchError,
|
||||
@ -398,16 +378,12 @@ testRun(void)
|
||||
",\"db-version\":\"15\"}\n");
|
||||
|
||||
// Single repo config - error when checking archive mode setting on database
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, "off", NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, "off", NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1),
|
||||
HRN_PQ_SCRIPT_CLOSE(8));
|
||||
|
||||
// Error on primary but standby check ok
|
||||
TEST_ERROR(cmdCheck(), ArchiveDisabledError, "archive_mode must be enabled");
|
||||
@ -423,16 +399,12 @@ testRun(void)
|
||||
hrnCfgArgKeyRawZ(argListRepo2, cfgOptRepoPath, 2, TEST_PATH "/repo2");
|
||||
HRN_CFG_LOAD(cfgCmdCheck, argListRepo2);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_15, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
// Stanza has not yet been created on repo2 but is created (and checked) on repo1
|
||||
TEST_ERROR_FMT(
|
||||
@ -489,14 +461,11 @@ testRun(void)
|
||||
",\"db-version\":\"15\"}\n");
|
||||
|
||||
// Error when WAL segment not found
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "1/1"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(1, "wal", "000000010000000100000001"),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(1, "1/1"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(1, "wal", "000000010000000100000001"),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
cmdCheck(), ArchiveTimeoutError,
|
||||
@ -540,14 +509,11 @@ testRun(void)
|
||||
bufUsedSet(buffer, bufSize(buffer));
|
||||
|
||||
// WAL segment switch is performed once for all repos
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "1/1"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(1, "wal", "000000010000000100000001"),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(1, "1/1"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(1, "wal", "000000010000000100000001"),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
HRN_STORAGE_PUT(
|
||||
storageRepoIdxWrite(0), STORAGE_REPO_ARCHIVE "/15-1/000000010000000100000001-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
@ -609,15 +575,12 @@ testRun(void)
|
||||
|
||||
DbGetResult db = {0};
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_11, "/badpath", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_11, "/badpath", true, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1),
|
||||
HRN_PQ_SCRIPT_CLOSE(8));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(false, false, false), "get primary and standby");
|
||||
|
||||
@ -676,12 +639,9 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
|
||||
HRN_CFG_LOAD(cfgCmdCheck, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, "always", NULL),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, "always", NULL),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
TEST_ERROR(
|
||||
|
@ -565,11 +565,8 @@ testRun(void)
|
||||
// Create pg_control
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_93);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg", false, NULL, NULL));
|
||||
|
||||
TEST_RESULT_VOID(cmdStanzaCreate(), "stanza create - db online");
|
||||
TEST_RESULT_LOG("P00 INFO: stanza-create for stanza 'db' on repo1");
|
||||
@ -586,11 +583,8 @@ testRun(void)
|
||||
.comment = "stanza created");
|
||||
|
||||
HRN_CFG_LOAD(cfgCmdStanzaUpgrade, argList);
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_93, TEST_PATH "/pg", false, NULL, NULL));
|
||||
|
||||
TEST_RESULT_VOID(cmdStanzaUpgrade(), "stanza upgrade - db online");
|
||||
TEST_RESULT_LOG(
|
||||
@ -603,11 +597,8 @@ testRun(void)
|
||||
// Create pg_control with different version
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_10);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, NULL, NULL),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_11, TEST_PATH "/pg", false, NULL, NULL));
|
||||
|
||||
TEST_ERROR(
|
||||
pgValidate(), DbMismatchError,
|
||||
@ -621,11 +612,8 @@ testRun(void)
|
||||
// Create pg_control
|
||||
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_15);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg2", false, NULL, NULL),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg2", false, NULL, NULL));
|
||||
|
||||
TEST_ERROR(
|
||||
pgValidate(), DbMismatchError,
|
||||
@ -651,12 +639,9 @@ testRun(void)
|
||||
// Create pg_control for standby
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_94);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_13, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(2, "dbname='postgres' port=5434", PG_VERSION_13, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_13, TEST_PATH "/pg", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(2, "dbname='postgres' port=5434", PG_VERSION_13, TEST_PATH "/pg1", false, NULL, NULL));
|
||||
|
||||
PgControl pgControl = {0};
|
||||
TEST_ASSIGN(pgControl, pgValidate(), "validate primary on pg2");
|
||||
|
@ -17,36 +17,36 @@ Test Database
|
||||
Macro to check that replay is making progress -- this does not seem useful enough to be included in the pq harness header
|
||||
***********************************************************************************************************************************/
|
||||
#define \
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS( \
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS( \
|
||||
sessionParam, walNameParam, lsnNameParam, targetLsnParam, targetReachedParam, replayLsnParam, replayLastLsnParam, \
|
||||
replayProgressParam, sleepParam) \
|
||||
{.session = sessionParam, \
|
||||
.function = HRNPQ_SENDQUERY, \
|
||||
.function = HRN_PQ_SENDQUERY, \
|
||||
.param = \
|
||||
"[\"select replayLsn::text,\\n" \
|
||||
" (replayLsn > '" targetLsnParam "')::bool as targetReached,\\n" \
|
||||
" (replayLsn > '" replayLastLsnParam "')::bool as replayProgress\\n" \
|
||||
" from pg_catalog.pg_last_" walNameParam "_replay_" lsnNameParam "() as replayLsn\"]", \
|
||||
.resultInt = 1, .sleep = sleepParam}, \
|
||||
{.session = sessionParam, .function = HRNPQ_CONSUMEINPUT}, \
|
||||
{.session = sessionParam, .function = HRNPQ_ISBUSY}, \
|
||||
{.session = sessionParam, .function = HRNPQ_GETRESULT}, \
|
||||
{.session = sessionParam, .function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK}, \
|
||||
{.session = sessionParam, .function = HRNPQ_NTUPLES, .resultInt = 1}, \
|
||||
{.session = sessionParam, .function = HRNPQ_NFIELDS, .resultInt = 3}, \
|
||||
{.session = sessionParam, .function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_TEXT}, \
|
||||
{.session = sessionParam, .function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_BOOL}, \
|
||||
{.session = sessionParam, .function = HRNPQ_FTYPE, .param = "[2]", .resultInt = HRNPQ_TYPE_BOOL}, \
|
||||
{.session = sessionParam, .function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = replayLsnParam}, \
|
||||
{.session = sessionParam, .function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = cvtBoolToConstZ(targetReachedParam)}, \
|
||||
{.session = sessionParam, .function = HRNPQ_GETVALUE, .param = "[0,2]", .resultZ = cvtBoolToConstZ(replayProgressParam)}, \
|
||||
{.session = sessionParam, .function = HRNPQ_CLEAR}, \
|
||||
{.session = sessionParam, .function = HRNPQ_GETRESULT, .resultNull = true}
|
||||
{.session = sessionParam, .function = HRN_PQ_CONSUMEINPUT}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_ISBUSY}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_GETRESULT}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_NTUPLES, .resultInt = 1}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_NFIELDS, .resultInt = 3}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_TEXT}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_FTYPE, .param = "[1]", .resultInt = HRN_PQ_TYPE_BOOL}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_FTYPE, .param = "[2]", .resultInt = HRN_PQ_TYPE_BOOL}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = replayLsnParam}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_GETVALUE, .param = "[0,1]", .resultZ = cvtBoolToConstZ(targetReachedParam)}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_GETVALUE, .param = "[0,2]", .resultZ = cvtBoolToConstZ(replayProgressParam)}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_CLEAR}, \
|
||||
{.session = sessionParam, .function = HRN_PQ_GETRESULT, .resultNull = true}
|
||||
|
||||
#define \
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10( \
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10( \
|
||||
sessionParam, targetLsnParam, targetReachedParam, replayLsnParam, replayLastLsnParam, replayProgressParam, sleepParam) \
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS( \
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS( \
|
||||
sessionParam, "wal", "lsn", targetLsnParam, targetReachedParam, replayLsnParam, replayLastLsnParam, replayProgressParam, \
|
||||
sleepParam)
|
||||
|
||||
@ -59,7 +59,7 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// PQfinish() is strictly checked
|
||||
harnessPqScriptStrictSet(true);
|
||||
hrnPqScriptStrictSet(true);
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("Db and dbProtocol()"))
|
||||
@ -79,28 +79,24 @@ testRun(void)
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList, .role = cfgCmdRoleRemote);
|
||||
|
||||
// Set script
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN(1, "dbname='testdb' port=5432"),
|
||||
HRNPQ_MACRO_SET_SEARCH_PATH(1),
|
||||
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
|
||||
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_93, TEST_PATH "/pg", NULL, NULL),
|
||||
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN(1, "dbname='testdb' port=5432"),
|
||||
HRN_PQ_SCRIPT_SET_SEARCH_PATH(1),
|
||||
HRN_PQ_SCRIPT_SET_CLIENT_ENCODING(1),
|
||||
HRN_PQ_SCRIPT_VALIDATE_QUERY(1, PG_VERSION_93, TEST_PATH "/pg", NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET_APPLICATION_NAME(1),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false),
|
||||
HRN_PQ_SCRIPT_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_OPEN(1, "dbname='testdb' port=5432"),
|
||||
HRNPQ_MACRO_SET_SEARCH_PATH(1),
|
||||
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
|
||||
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_93, TEST_PATH "/pg", NULL, NULL),
|
||||
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "2/3"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(1, "xlog", "000000030000000200000003"),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_OPEN(1, "dbname='testdb' port=5432"),
|
||||
HRN_PQ_SCRIPT_SET_SEARCH_PATH(1),
|
||||
HRN_PQ_SCRIPT_SET_CLIENT_ENCODING(1),
|
||||
HRN_PQ_SCRIPT_VALIDATE_QUERY(1, PG_VERSION_93, TEST_PATH "/pg", NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET_APPLICATION_NAME(1),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false),
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(1, "2/3"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(1, "xlog", "000000030000000200000003"),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
// Create server
|
||||
ProtocolServer *server = NULL;
|
||||
@ -215,50 +211,43 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error when unable to select any pg_settings");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN(1, "dbname='backupdb' port=5432"),
|
||||
HRNPQ_MACRO_SET_SEARCH_PATH(1),
|
||||
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
|
||||
HRN_PQ_SCRIPT_OPEN(1, "dbname='backupdb' port=5432"),
|
||||
HRN_PQ_SCRIPT_SET_SEARCH_PATH(1),
|
||||
HRN_PQ_SCRIPT_SET_CLIENT_ENCODING(1),
|
||||
|
||||
// Return NULL for a row in pg_settings
|
||||
{
|
||||
.session = 1,
|
||||
.function = HRNPQ_SENDQUERY,
|
||||
.param =
|
||||
"[\"select (select setting from pg_catalog.pg_settings where name = 'server_version_num')::int4,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'data_directory')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'archive_mode')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'archive_command')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'checkpoint_timeout')::int4\"]",
|
||||
.resultInt = 1,
|
||||
},
|
||||
{.session = 1, .function = HRNPQ_CONSUMEINPUT},
|
||||
{.session = 1, .function = HRNPQ_ISBUSY},
|
||||
{.session = 1, .function = HRNPQ_GETRESULT},
|
||||
{.session = 1, .function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.session = 1, .function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.session = 1, .function = HRNPQ_NFIELDS, .resultInt = 5},
|
||||
{.session = 1, .function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_INT4},
|
||||
{.session = 1, .function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRNPQ_FTYPE, .param = "[2]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRNPQ_FTYPE, .param = "[3]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRNPQ_FTYPE, .param = "[4]", .resultInt = HRNPQ_TYPE_INT4},
|
||||
{.session = 1, .function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = "0"},
|
||||
{.session = 1, .function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = "value"},
|
||||
{.session = 1, .function = HRNPQ_GETVALUE, .param = "[0,2]", .resultZ = "value"},
|
||||
{.session = 1, .function = HRNPQ_GETVALUE, .param = "[0,3]", .resultZ = ""},
|
||||
{.session = 1, .function = HRNPQ_GETISNULL, .param = "[0,3]", .resultInt = 1},
|
||||
{.session = 1, .function = HRNPQ_GETVALUE, .param = "[0,4]", .resultZ = "300"},
|
||||
{.session = 1, .function = HRNPQ_CLEAR},
|
||||
{.session = 1, .function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.session = 1, .function = HRN_PQ_SENDQUERY,
|
||||
.param =
|
||||
"[\"select (select setting from pg_catalog.pg_settings where name = 'server_version_num')::int4,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'data_directory')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'archive_mode')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'archive_command')::text,"
|
||||
" (select setting from pg_catalog.pg_settings where name = 'checkpoint_timeout')::int4\"]",
|
||||
.resultInt = 1},
|
||||
{.session = 1, .function = HRN_PQ_CONSUMEINPUT},
|
||||
{.session = 1, .function = HRN_PQ_ISBUSY},
|
||||
{.session = 1, .function = HRN_PQ_GETRESULT},
|
||||
{.session = 1, .function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.session = 1, .function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.session = 1, .function = HRN_PQ_NFIELDS, .resultInt = 5},
|
||||
{.session = 1, .function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_INT4},
|
||||
{.session = 1, .function = HRN_PQ_FTYPE, .param = "[1]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRN_PQ_FTYPE, .param = "[2]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRN_PQ_FTYPE, .param = "[3]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.session = 1, .function = HRN_PQ_FTYPE, .param = "[4]", .resultInt = HRN_PQ_TYPE_INT4},
|
||||
{.session = 1, .function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = "0"},
|
||||
{.session = 1, .function = HRN_PQ_GETVALUE, .param = "[0,1]", .resultZ = "value"},
|
||||
{.session = 1, .function = HRN_PQ_GETVALUE, .param = "[0,2]", .resultZ = "value"},
|
||||
{.session = 1, .function = HRN_PQ_GETVALUE, .param = "[0,3]", .resultZ = ""},
|
||||
{.session = 1, .function = HRN_PQ_GETISNULL, .param = "[0,3]", .resultInt = 1},
|
||||
{.session = 1, .function = HRN_PQ_GETVALUE, .param = "[0,4]", .resultZ = "300"},
|
||||
{.session = 1, .function = HRN_PQ_CLEAR},
|
||||
{.session = 1, .function = HRN_PQ_GETRESULT, .resultNull = true},
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
dbGet(true, true, false), DbConnectError,
|
||||
@ -275,32 +264,28 @@ testRun(void)
|
||||
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_93, .checkpoint = pgLsnFromStr(STRDEF("2/3")));
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='backupdb' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='backupdb' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Get start time
|
||||
HRNPQ_MACRO_TIME_QUERY(1, 1000),
|
||||
HRN_PQ_SCRIPT_TIME_QUERY(1, 1000),
|
||||
|
||||
// Start backup errors on advisory lock
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, false),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, false),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
|
||||
HRNPQ_MACRO_START_BACKUP_LE_95(1, false, "2/3", "000000010000000200000003"),
|
||||
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
|
||||
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_IS_IN_BACKUP(1, false),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_LE_95(1, false, "2/3", "000000010000000200000003"),
|
||||
HRN_PQ_SCRIPT_DATABASE_LIST_1(1, "test1"),
|
||||
HRN_PQ_SCRIPT_TABLESPACE_LIST_0(1),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, "2/4", "000000010000000200000004"),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_LE_95(1, "2/4", "000000010000000200000004"),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
DbGetResult db = {0};
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
@ -334,29 +319,25 @@ testRun(void)
|
||||
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_93, .checkpoint = pgLsnFromStr(STRDEF("2/5")));
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='backupdb' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='backupdb' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Start backup when backup is in progress
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_IS_IN_BACKUP(1, true),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_IS_IN_BACKUP(1, true),
|
||||
|
||||
// Stop old backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, "1/1", "000000010000000100000001"),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_LE_95(1, "1/1", "000000010000000100000001"),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_START_BACKUP_LE_95(1, true, "2/5", "000000010000000200000005"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_LE_95(1, true, "2/5", "000000010000000200000005"),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, "2/6", "000000010000000200000006"),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_LE_95(1, "2/6", "000000010000000200000006"),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
|
||||
@ -375,34 +356,30 @@ testRun(void)
|
||||
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_93, .checkpoint = pgLsnFromStr(STRDEF("3/3")));
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='backupdb' port=5432", PG_VERSION_96, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='backupdb' port=5432", PG_VERSION_96, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Start backup with timeline error
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, "000000020000000300000002"),
|
||||
HRNPQ_MACRO_START_BACKUP_96(1, false, "3/3", "000000020000000300000003"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_LE_96(1, "000000020000000300000002"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_96(1, false, "3/3", "000000020000000300000003"),
|
||||
|
||||
// Start backup with checkpoint error
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, "000000010000000400000003"),
|
||||
HRNPQ_MACRO_START_BACKUP_96(1, false, "4/4", "000000010000000400000004"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_LE_96(1, "000000010000000400000003"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_96(1, false, "4/4", "000000010000000400000004"),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, "000000010000000300000002"),
|
||||
HRNPQ_MACRO_START_BACKUP_96(1, false, "3/3", "000000010000000300000003"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_LE_96(1, "000000010000000300000002"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_96(1, false, "3/3", "000000010000000300000003"),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_96(1, "3/4", "000000010000000300000004", false),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_96(1, "3/4", "000000010000000300000004", false),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
|
||||
@ -440,39 +417,35 @@ testRun(void)
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_93, .timeline = 5, .checkpoint = pgLsnFromStr(STRDEF("5/4")));
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(1), PG_VERSION_93, .timeline = 5, .checkpoint = pgLsnFromStr(STRDEF("5/4")));
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Connect to standby
|
||||
HRNPQ_MACRO_OPEN_GE_93(2, "dbname='postgres' port=5433", PG_VERSION_95, TEST_PATH "/pg2", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(2, "dbname='postgres' port=5433", PG_VERSION_95, TEST_PATH "/pg2", true, NULL, NULL),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_START_BACKUP_LE_95(1, false, "5/4", "000000050000000500000004"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_LE_95(1, false, "5/4", "000000050000000500000004"),
|
||||
|
||||
// Wait for standby to sync
|
||||
HRNPQ_MACRO_REPLAY_WAIT_LE_95(2, "5/4"),
|
||||
HRN_PQ_SCRIPT_REPLAY_WAIT_LE_95(2, "5/4"),
|
||||
|
||||
// Ping
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, true),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, true),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false),
|
||||
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, false),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, true),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, true),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(2, true),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, false),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, true),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, true),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(2, true),
|
||||
|
||||
// Close standby
|
||||
HRNPQ_MACRO_CLOSE(2),
|
||||
HRN_PQ_SCRIPT_CLOSE(2),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(false, true, true), "get primary and standby");
|
||||
|
||||
@ -505,85 +478,78 @@ testRun(void)
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(0), PG_VERSION_93, .timeline = 5, .checkpoint = pgLsnFromStr(STRDEF("5/5")));
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(1), PG_VERSION_93, .timeline = 5, .checkpoint = pgLsnFromStr(STRDEF("5/5")));
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_10, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_10, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Connect to standby
|
||||
HRNPQ_MACRO_OPEN_GE_96(2, "dbname='postgres' port=5433", PG_VERSION_10, TEST_PATH "/pg2", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(2, "dbname='postgres' port=5433", PG_VERSION_10, TEST_PATH "/pg2", true, NULL, NULL),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_GE_10(1, "000000050000000500000005"),
|
||||
HRNPQ_MACRO_START_BACKUP_GE_10(1, false, "5/5", "000000050000000500000005"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_GE_10(1, "000000050000000500000005"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_GE_10(1, false, "5/5", "000000050000000500000005"),
|
||||
|
||||
// Switch WAL segment so it can be checked
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "5/5"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(1, "wal", "000000050000000500000005"),
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(1, "5/5"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(1, "wal", "000000050000000500000005"),
|
||||
|
||||
// Standby returns NULL lsn
|
||||
{
|
||||
.session = 2,
|
||||
.function = HRNPQ_SENDQUERY,
|
||||
.param =
|
||||
"[\"select replayLsn::text,\\n"
|
||||
" (replayLsn > '5/5')::bool as targetReached\\n"
|
||||
" from pg_catalog.pg_last_wal_replay_lsn() as replayLsn\"]",
|
||||
.resultInt = 1,
|
||||
},
|
||||
{.session = 2, .function = HRNPQ_CONSUMEINPUT},
|
||||
{.session = 2, .function = HRNPQ_ISBUSY},
|
||||
{.session = 2, .function = HRNPQ_GETRESULT},
|
||||
{.session = 2, .function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.session = 2, .function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.session = 2, .function = HRNPQ_NFIELDS, .resultInt = 2},
|
||||
{.session = 2, .function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.session = 2, .function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_BOOL},
|
||||
{.session = 2, .function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = ""},
|
||||
{.session = 2, .function = HRNPQ_GETISNULL, .param = "[0,0]", .resultInt = 1},
|
||||
{.session = 2, .function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = "false"},
|
||||
{.session = 2, .function = HRNPQ_CLEAR},
|
||||
{.session = 2, .function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.session = 2, .function = HRN_PQ_SENDQUERY,
|
||||
.param =
|
||||
"[\"select replayLsn::text,\\n"
|
||||
" (replayLsn > '5/5')::bool as targetReached\\n"
|
||||
" from pg_catalog.pg_last_wal_replay_lsn() as replayLsn\"]",
|
||||
.resultInt = 1},
|
||||
{.session = 2, .function = HRN_PQ_CONSUMEINPUT},
|
||||
{.session = 2, .function = HRN_PQ_ISBUSY},
|
||||
{.session = 2, .function = HRN_PQ_GETRESULT},
|
||||
{.session = 2, .function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.session = 2, .function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.session = 2, .function = HRN_PQ_NFIELDS, .resultInt = 2},
|
||||
{.session = 2, .function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.session = 2, .function = HRN_PQ_FTYPE, .param = "[1]", .resultInt = HRN_PQ_TYPE_BOOL},
|
||||
{.session = 2, .function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = ""},
|
||||
{.session = 2, .function = HRN_PQ_GETISNULL, .param = "[0,0]", .resultInt = 1},
|
||||
{.session = 2, .function = HRN_PQ_GETVALUE, .param = "[0,1]", .resultZ = "false"},
|
||||
{.session = 2, .function = HRN_PQ_CLEAR},
|
||||
{.session = 2, .function = HRN_PQ_GETRESULT, .resultNull = true},
|
||||
|
||||
// Timeout waiting for sync
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 100),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 100),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 100),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 100),
|
||||
|
||||
// Checkpoint target timeout waiting for sync
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_GE_10(2, "5/5", true, "5/5"),
|
||||
HRNPQ_MACRO_CHECKPOINT(2),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", false, "5/4", 100),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", false, "5/4", 100),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_GE_10(2, "5/5", true, "5/5"),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT(2),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", false, "5/4", 100),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", false, "5/4", 100),
|
||||
|
||||
// Wait for standby to sync
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/4", "5/3", true, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", true, "5/5", "5/4", true, 0),
|
||||
HRNPQ_MACRO_CHECKPOINT(2),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/4", "5/3", true, 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", true, "5/5", "5/4", true, 0),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT(2),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
|
||||
// Fail on timeline mismatch
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/4", "5/3", true, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", true, "5/5", "5/4", true, 0),
|
||||
HRNPQ_MACRO_CHECKPOINT(2),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/4", "5/3", true, 0),
|
||||
HRN_PQ_SCRIPT_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", true, "5/5", "5/4", true, 0),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT(2),
|
||||
HRN_PQ_SCRIPT_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
|
||||
// Close standby
|
||||
HRNPQ_MACRO_CLOSE(2),
|
||||
HRN_PQ_SCRIPT_CLOSE(2),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_GE_10(1, "5/6", "000000050000000500000006", true),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_GE_10(1, "5/6", "000000050000000500000006", true),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(false, true, true), "get primary and standby");
|
||||
|
||||
@ -638,21 +604,17 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptDbTimeout, "299");
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_14, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_14, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_GE_10(1, "000000050000000500000004"),
|
||||
HRNPQ_MACRO_START_BACKUP_GE_10(1, false, "5/5", "000000050000000500000005"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_GE_10(1, "000000050000000500000004"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_GE_10(1, false, "5/5", "000000050000000500000005"),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
TEST_ASSIGN(backupStartResult, dbBackupStart(db.primary, false, false, true), "start backup");
|
||||
@ -674,24 +636,20 @@ testRun(void)
|
||||
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 1, TEST_PATH "/pg1");
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
// Connect to primary
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_15, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
|
||||
// Start backup
|
||||
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
|
||||
HRNPQ_MACRO_CURRENT_WAL_GE_10(1, "000000060000000600000005"),
|
||||
HRNPQ_MACRO_START_BACKUP_GE_15(1, false, "6/6", "000000060000000600000006"),
|
||||
HRN_PQ_SCRIPT_ADVISORY_LOCK(1, true),
|
||||
HRN_PQ_SCRIPT_CURRENT_WAL_GE_10(1, "000000060000000600000005"),
|
||||
HRN_PQ_SCRIPT_START_BACKUP_GE_15(1, false, "6/6", "000000060000000600000006"),
|
||||
|
||||
// Stop backup
|
||||
HRNPQ_MACRO_STOP_BACKUP_GE_15(1, "6/7", "000000060000000600000006", false),
|
||||
HRN_PQ_SCRIPT_STOP_BACKUP_GE_15(1, "6/7", "000000060000000600000006", false),
|
||||
|
||||
// Close primary
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
TEST_ASSIGN(backupStartResult, dbBackupStart(db.primary, false, false, true), "start backup");
|
||||
@ -727,14 +685,11 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error connecting to primary");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432 user='bob'\"]"},
|
||||
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRNPQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.function = HRNPQ_FINISH},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432 user='bob'\"]"},
|
||||
{.function = HRN_PQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRN_PQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.function = HRN_PQ_FINISH});
|
||||
|
||||
TEST_ERROR(
|
||||
dbGet(true, true, false), DbConnectError,
|
||||
@ -747,17 +702,14 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("only available cluster is a standby");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN(1, "dbname='postgres' port=5432 user='bob'"),
|
||||
HRNPQ_MACRO_SET_SEARCH_PATH(1),
|
||||
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
|
||||
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_94, TEST_PATH "/pg", NULL, NULL),
|
||||
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, true),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN(1, "dbname='postgres' port=5432 user='bob'"),
|
||||
HRN_PQ_SCRIPT_SET_SEARCH_PATH(1),
|
||||
HRN_PQ_SCRIPT_SET_CLIENT_ENCODING(1),
|
||||
HRN_PQ_SCRIPT_VALIDATE_QUERY(1, PG_VERSION_94, TEST_PATH "/pg", NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET_APPLICATION_NAME(1),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, true),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
dbGet(true, true, false), DbConnectError,
|
||||
@ -767,29 +719,24 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("standby cluster required but not found");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN(1, "dbname='postgres' port=5432 user='bob'"),
|
||||
HRNPQ_MACRO_SET_SEARCH_PATH(1),
|
||||
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
|
||||
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_94, TEST_PATH "/pg", NULL, NULL),
|
||||
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
|
||||
HRNPQ_MACRO_IS_STANDBY_QUERY(1, false),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN(1, "dbname='postgres' port=5432 user='bob'"),
|
||||
HRN_PQ_SCRIPT_SET_SEARCH_PATH(1),
|
||||
HRN_PQ_SCRIPT_SET_CLIENT_ENCODING(1),
|
||||
HRN_PQ_SCRIPT_VALIDATE_QUERY(1, PG_VERSION_94, TEST_PATH "/pg", NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET_APPLICATION_NAME(1),
|
||||
HRN_PQ_SCRIPT_IS_STANDBY_QUERY(1, false),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(dbGet(false, false, true), DbConnectError, "unable to find standby cluster - cannot proceed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("primary cluster found");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432 user='bob'", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(
|
||||
1, "dbname='postgres' port=5432 user='bob'", PG_VERSION_93, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(result, dbGet(true, true, false), "get primary only");
|
||||
|
||||
@ -816,32 +763,24 @@ testRun(void)
|
||||
// Create control file
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(1), PG_VERSION_93);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_93(8, "dbname='postgres' port=5433", PG_VERSION_95, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(1, "dbname='postgres' port=5432", PG_VERSION_95, TEST_PATH "/pg1", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_93(8, "dbname='postgres' port=5433", PG_VERSION_95, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(1),
|
||||
HRN_PQ_SCRIPT_CLOSE(8));
|
||||
|
||||
TEST_ERROR(dbGet(true, true, false), DbConnectError, "more than one primary cluster found");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("two standbys found but no primary");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, TEST_PATH "/pg8", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_96, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_96, TEST_PATH "/pg8", true, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ERROR(
|
||||
dbGet(false, true, false), DbConnectError,
|
||||
@ -851,16 +790,12 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("two standbys and primary not required");
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_10, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_10, TEST_PATH "/pg8", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_10, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5433", PG_VERSION_10, TEST_PATH "/pg8", true, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(result, dbGet(false, false, false), "get standbys");
|
||||
|
||||
@ -887,26 +822,22 @@ testRun(void)
|
||||
hrnCfgArgKeyRawZ(argList, cfgOptPgPort, 8, "5434");
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
HRNPQ_MACRO_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_12, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(1, "dbname='postgres' port=5432", PG_VERSION_12, TEST_PATH "/pg1", true, NULL, NULL),
|
||||
|
||||
// pg4 error
|
||||
{.session = 4, .function = HRNPQ_CONNECTDB, .param = "[\"dbname='postgres' port=5433\"]"},
|
||||
{.session = 4, .function = HRNPQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.session = 4, .function = HRNPQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.session = 4, .function = HRNPQ_FINISH},
|
||||
{.session = 4, .function = HRN_PQ_CONNECTDB, .param = "[\"dbname='postgres' port=5433\"]"},
|
||||
{.session = 4, .function = HRN_PQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.session = 4, .function = HRN_PQ_ERRORMESSAGE, .resultZ = "error"},
|
||||
{.session = 4, .function = HRN_PQ_FINISH},
|
||||
|
||||
HRNPQ_MACRO_OPEN_GE_96(8, "dbname='postgres' port=5434", PG_VERSION_12, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
HRN_PQ_SCRIPT_OPEN_GE_96(8, "dbname='postgres' port=5434", PG_VERSION_12, TEST_PATH "/pg8", false, NULL, NULL),
|
||||
|
||||
HRNPQ_MACRO_CREATE_RESTORE_POINT(8, "2/3"),
|
||||
HRNPQ_MACRO_WAL_SWITCH(8, "wal", "000000010000000200000003"),
|
||||
HRN_PQ_SCRIPT_CREATE_RESTORE_POINT(8, "2/3"),
|
||||
HRN_PQ_SCRIPT_WAL_SWITCH(8, "wal", "000000010000000200000003"),
|
||||
|
||||
HRNPQ_MACRO_CLOSE(8),
|
||||
HRNPQ_MACRO_CLOSE(1),
|
||||
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
HRN_PQ_SCRIPT_CLOSE(8),
|
||||
HRN_PQ_SCRIPT_CLOSE(1));
|
||||
|
||||
TEST_ASSIGN(result, dbGet(false, true, false), "get primary and standy");
|
||||
|
||||
|
@ -23,7 +23,7 @@ testRun(void)
|
||||
|
||||
// PQfinish() is strictly checked
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptStrictSet(true);
|
||||
hrnPqScriptStrictSet(true);
|
||||
#endif
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -48,14 +48,11 @@ testRun(void)
|
||||
"\tIs the server running locally and accepting connections on that socket?"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_CONNECTDB, .param = "[\"dbname='postg \\\\'\\\\\\\\res' port=5433\"]"},
|
||||
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRNPQ_ERRORMESSAGE, .resultZ = TEST_PQ_ERROR},
|
||||
{.function = HRNPQ_FINISH},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_CONNECTDB, .param = "[\"dbname='postg \\\\'\\\\\\\\res' port=5433\"]"},
|
||||
{.function = HRN_PQ_STATUS, .resultInt = CONNECTION_BAD},
|
||||
{.function = HRN_PQ_ERRORMESSAGE, .resultZ = TEST_PQ_ERROR},
|
||||
{.function = HRN_PQ_FINISH});
|
||||
#endif
|
||||
|
||||
PgClient *client = NULL;
|
||||
@ -81,15 +78,12 @@ testRun(void)
|
||||
#define TEST_QUERY "select bogus from pg_class"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432\"]"},
|
||||
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_OK},
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 0},
|
||||
{.function = HRNPQ_ERRORMESSAGE, .resultZ = TEST_PQ_ERROR "\n"},
|
||||
{.function = HRNPQ_FINISH},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432\"]"},
|
||||
{.function = HRN_PQ_STATUS, .resultInt = CONNECTION_OK},
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 0},
|
||||
{.function = HRN_PQ_ERRORMESSAGE, .resultZ = TEST_PQ_ERROR "\n"},
|
||||
{.function = HRN_PQ_FINISH});
|
||||
#endif
|
||||
|
||||
TEST_ASSIGN(client, pgClientOpen(pgClientNew(NULL, 5432, STRDEF("postgres"), NULL, 3000)), "new client");
|
||||
@ -111,15 +105,10 @@ testRun(void)
|
||||
TEST_TITLE("connect");
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{
|
||||
.function = HRNPQ_CONNECTDB,
|
||||
.param = "[\"dbname='postgres' port=5432 user='" TEST_USER "' host='/var/run/postgresql'\"]",
|
||||
},
|
||||
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_OK},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_CONNECTDB,
|
||||
.param = "[\"dbname='postgres' port=5432 user='" TEST_USER "' host='/var/run/postgresql'\"]"},
|
||||
{.function = HRN_PQ_STATUS, .resultInt = CONNECTION_OK});
|
||||
#endif
|
||||
|
||||
TEST_ASSIGN(
|
||||
@ -136,18 +125,15 @@ testRun(void)
|
||||
#define TEST_QUERY "select bogus from pg_class"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_FATAL_ERROR},
|
||||
{.function = HRNPQ_RESULTERRORMESSAGE, .resultZ = TEST_PQ_ERROR " \n"},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_FATAL_ERROR},
|
||||
{.function = HRN_PQ_RESULTERRORMESSAGE, .resultZ = TEST_PQ_ERROR " \n"},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -163,19 +149,16 @@ testRun(void)
|
||||
#define TEST_QUERY "select pg_sleep(3000)"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT, .sleep = 600},
|
||||
{.function = HRNPQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRNPQ_GETCANCEL},
|
||||
{.function = HRNPQ_CANCEL, .resultInt = 1},
|
||||
{.function = HRNPQ_FREECANCEL},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT, .sleep = 600},
|
||||
{.function = HRN_PQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRN_PQ_GETCANCEL},
|
||||
{.function = HRN_PQ_CANCEL, .resultInt = 1},
|
||||
{.function = HRN_PQ_FREECANCEL},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -191,18 +174,15 @@ testRun(void)
|
||||
#define TEST_PQ_ERROR "test error"
|
||||
#define TEST_QUERY "select pg_sleep(3000)"
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT, .sleep = 300},
|
||||
{.function = HRNPQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT, .sleep = 300},
|
||||
{.function = HRNPQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRNPQ_GETCANCEL},
|
||||
{.function = HRNPQ_CANCEL, .resultInt = 0, .resultZ = TEST_PQ_ERROR},
|
||||
{.function = HRNPQ_FREECANCEL},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT, .sleep = 300},
|
||||
{.function = HRN_PQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT, .sleep = 300},
|
||||
{.function = HRN_PQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRN_PQ_GETCANCEL},
|
||||
{.function = HRN_PQ_CANCEL, .resultInt = 0, .resultZ = TEST_PQ_ERROR},
|
||||
{.function = HRN_PQ_FREECANCEL});
|
||||
|
||||
TEST_ERROR(
|
||||
pgClientQuery(client, STRDEF(TEST_QUERY), pgClientQueryResultColumn), DbQueryError,
|
||||
@ -218,14 +198,11 @@ testRun(void)
|
||||
|
||||
#define TEST_QUERY "select 1"
|
||||
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT, .sleep = 600},
|
||||
{.function = HRNPQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRNPQ_GETCANCEL, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT, .sleep = 600},
|
||||
{.function = HRN_PQ_ISBUSY, .resultInt = 1},
|
||||
{.function = HRN_PQ_GETCANCEL, .resultNull = true});
|
||||
|
||||
TEST_ERROR(
|
||||
pgClientQuery(client, STRDEF(TEST_QUERY), pgClientQueryResultColumn), DbQueryError,
|
||||
@ -240,17 +217,14 @@ testRun(void)
|
||||
#define TEST_QUERY "set client_encoding = 'UTF8'"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -265,17 +239,14 @@ testRun(void)
|
||||
#define TEST_QUERY "select * from pg_class limit 1"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -290,17 +261,14 @@ testRun(void)
|
||||
#define TEST_QUERY "set client_encoding = 'UTF8'"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_RESULT_PTR(pgClientQuery(client, STRDEF(TEST_QUERY), pgClientQueryResultAny), NULL, "execute set");
|
||||
@ -313,17 +281,14 @@ testRun(void)
|
||||
#define TEST_QUERY "do $$ begin raise notice 'mememe'; end $$"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_COMMAND_OK},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_RESULT_PTR(pgClientQuery(client, STRDEF(TEST_QUERY), pgClientQueryResultNone), NULL, "execute do block");
|
||||
@ -336,21 +301,18 @@ testRun(void)
|
||||
#define TEST_QUERY "select clock_timestamp()"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 1},
|
||||
{.function = HRNPQ_FTYPE, .param = "[0]", .resultInt = 1184},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = "2019-07-25 12:06:09.000282+00"},
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 1},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = 1184},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = "2019-07-25 12:06:09.000282+00"},
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -368,37 +330,34 @@ testRun(void)
|
||||
" order by relname"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 2},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 4},
|
||||
{.function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_OID},
|
||||
{.function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.function = HRNPQ_FTYPE, .param = "[2]", .resultInt = HRNPQ_TYPE_TEXT},
|
||||
{.function = HRNPQ_FTYPE, .param = "[3]", .resultInt = HRNPQ_TYPE_BOOL},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 2},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 4},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_OID},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[1]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[2]", .resultInt = HRN_PQ_TYPE_TEXT},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[3]", .resultInt = HRN_PQ_TYPE_BOOL},
|
||||
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = "1259"},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = ""},
|
||||
{.function = HRNPQ_GETISNULL, .param = "[0,1]", .resultInt = 1},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,2]", .resultZ = "pg_class"},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,3]", .resultZ = "t"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = "1259"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,1]", .resultZ = ""},
|
||||
{.function = HRN_PQ_GETISNULL, .param = "[0,1]", .resultInt = 1},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,2]", .resultZ = "pg_class"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,3]", .resultZ = "t"},
|
||||
|
||||
{.function = HRNPQ_GETVALUE, .param = "[1,0]", .resultZ = "1255"},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[1,1]", .resultZ = ""},
|
||||
{.function = HRNPQ_GETISNULL, .param = "[1,1]", .resultInt = 0},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[1,2]", .resultZ = "pg_proc"},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[1,3]", .resultZ = "f"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[1,0]", .resultZ = "1255"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[1,1]", .resultZ = ""},
|
||||
{.function = HRN_PQ_GETISNULL, .param = "[1,1]", .resultInt = 0},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[1,2]", .resultZ = "pg_proc"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[1,3]", .resultZ = "f"},
|
||||
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -414,21 +373,18 @@ testRun(void)
|
||||
#define TEST_QUERY "select * from pg_class limit 2"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 2},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 1},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 2},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 1},
|
||||
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -443,26 +399,23 @@ testRun(void)
|
||||
#define TEST_QUERY "select 1259::oid, -9223372036854775807::int8"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 2},
|
||||
{.function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_OID},
|
||||
{.function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_INT8},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 2},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_OID},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[1]", .resultInt = HRN_PQ_TYPE_INT8},
|
||||
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = "1259"},
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = "-9223372036854775807"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = "1259"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,1]", .resultZ = "-9223372036854775807"},
|
||||
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -477,21 +430,18 @@ testRun(void)
|
||||
#define TEST_QUERY "select * from pg_class limit 1"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 2},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 2},
|
||||
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_ERROR(
|
||||
@ -506,24 +456,21 @@ testRun(void)
|
||||
#define TEST_QUERY "select -2147483647::int4"
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRNPQ_CONSUMEINPUT},
|
||||
{.function = HRNPQ_ISBUSY},
|
||||
{.function = HRNPQ_GETRESULT},
|
||||
{.function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_SENDQUERY, .param = "[\"" TEST_QUERY "\"]", .resultInt = 1},
|
||||
{.function = HRN_PQ_CONSUMEINPUT},
|
||||
{.function = HRN_PQ_ISBUSY},
|
||||
{.function = HRN_PQ_GETRESULT},
|
||||
{.function = HRN_PQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK},
|
||||
|
||||
{.function = HRNPQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRNPQ_NFIELDS, .resultInt = 1},
|
||||
{.function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_INT4},
|
||||
{.function = HRN_PQ_NTUPLES, .resultInt = 1},
|
||||
{.function = HRN_PQ_NFIELDS, .resultInt = 1},
|
||||
{.function = HRN_PQ_FTYPE, .param = "[0]", .resultInt = HRN_PQ_TYPE_INT4},
|
||||
|
||||
{.function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = "-2147483647"},
|
||||
{.function = HRN_PQ_GETVALUE, .param = "[0,0]", .resultZ = "-2147483647"},
|
||||
|
||||
{.function = HRNPQ_CLEAR},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
{.function = HRN_PQ_CLEAR},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
@ -536,12 +483,9 @@ testRun(void)
|
||||
TEST_TITLE("close connection");
|
||||
|
||||
#ifndef HARNESS_PQ_REAL
|
||||
harnessPqScriptSet((HarnessPq [])
|
||||
{
|
||||
{.function = HRNPQ_FINISH},
|
||||
{.function = HRNPQ_GETRESULT, .resultNull = true},
|
||||
{.function = NULL}
|
||||
});
|
||||
HRN_PQ_SCRIPT_SET(
|
||||
{.function = HRN_PQ_FINISH},
|
||||
{.function = HRN_PQ_GETRESULT, .resultNull = true});
|
||||
#endif
|
||||
TEST_RESULT_VOID(pgClientClose(client), "close client");
|
||||
TEST_RESULT_VOID(pgClientClose(client), "close client again");
|
||||
|
Loading…
Reference in New Issue
Block a user