1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-11 00:50:20 +02:00

Add local process shim.

Run the local process inside a forked child process instead of exec'ing it. This allows coverage to accumulate in the local process rather than needing to test the local protocol functions directly, resulting in better end-to-end testing and less test duplication. Another advantage is that the pgbackrest binary does not need to be built for the test.

The backup, restore, and verify command tests have been updated to use the new shim for coverage.
This commit is contained in:
David Steele
2021-05-21 12:45:00 -04:00
parent cab7a97ab6
commit ef63750e0b
7 changed files with 194 additions and 212 deletions

View File

@ -177,6 +177,14 @@
<p>Add <code>StringId</code> type.</p> <p>Add <code>StringId</code> type.</p>
</release-item> </release-item>
<release-item>
<commit subject="Factor local process exec out of protocolLocalGet()."/>
<commit subject="Add shim feature for unit tests."/>
<commit subject="Add local process shim."/>
<p>Add local processs shim.</p>
</release-item>
<release-item> <release-item>
<github-pull-request id="1381"/> <github-pull-request id="1381"/>

View File

@ -582,6 +582,12 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: protocol - name: protocol
total: 9 total: 9
harness:
name: protocol
shim:
protocol/helper:
function:
- protocolLocalExec
containerReq: true containerReq: true
binReq: true binReq: true
@ -760,7 +766,6 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: restore - name: restore
total: 12 total: 12
binReq: true
coverage: coverage:
- command/restore/file - command/restore/file
@ -783,7 +788,6 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: backup - name: backup
total: 10 total: 10
binReq: true
coverage: coverage:
- command/backup/backup - command/backup/backup
@ -814,7 +818,6 @@ unit:
# ---------------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------------
- name: verify - name: verify
total: 8 total: 8
binReq: true
coverage: coverage:
- command/verify/file - command/verify/file

View File

@ -0,0 +1,116 @@
/***********************************************************************************************************************************
Harness for Protocol Testing
***********************************************************************************************************************************/
#include "build.auto.h"
#include <stdlib.h>
#include <unistd.h>
#include "common/io/fdRead.h"
#include "common/io/fdWrite.h"
#include "common/fork.h"
#include "common/harnessConfig.h"
#include "common/harnessDebug.h"
#include "common/harnessLog.h"
#include "common/harnessProtocol.h"
/***********************************************************************************************************************************
Include shimmed C modules
***********************************************************************************************************************************/
{[SHIM_MODULE]}
/***********************************************************************************************************************************
Shim initialization state
***********************************************************************************************************************************/
static struct
{
bool localHandler;
const ProtocolServerHandler *localHandlerList;
unsigned int localHandlerListSize;
} hrnProtocolStatic;
/***********************************************************************************************************************************
Shim protocolLocalExec() to provide coverage as detailed in the hrnProtocolLocalShimInstall() documentation.
***********************************************************************************************************************************/
static void
protocolLocalExec(
ProtocolHelperClient *helper, ProtocolStorageType protocolStorageType, unsigned int hostIdx, unsigned int processId)
{
// Call the shim when initialized
if (hrnProtocolStatic.localHandler)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM_P(VOID, helper);
FUNCTION_HARNESS_PARAM(ENUM, protocolStorageType);
FUNCTION_HARNESS_PARAM(UINT, hostIdx);
FUNCTION_HARNESS_PARAM(UINT, processId);
FUNCTION_HARNESS_END();
// Create pipes to communicate with the subprocess. The names of the pipes are from the perspective of the parent process
// since the child process will use them only briefly before exec'ing.
int pipeRead[2];
int pipeWrite[2];
THROW_ON_SYS_ERROR(pipe(pipeRead) == -1, KernelError, "unable to create read pipe");
THROW_ON_SYS_ERROR(pipe(pipeWrite) == -1, KernelError, "unable to create write pipe");
// Exec command in the child process
if (forkSafe() == 0)
{
// Load configuration
const StringList *const paramList = protocolLocalParam(protocolStorageType, hostIdx, processId);
harnessCfgLoadRaw(strLstSize(paramList), strLstPtr(paramList));
// Change log process id to aid in debugging
hrnLogProcessIdSet(processId);
// Run server with provided handlers
String *name = strNewFmt(PROTOCOL_SERVICE_LOCAL "-shim-%u", processId);
IoRead *read = ioFdReadNew(name, pipeWrite[0], 5000);
ioReadOpen(read);
IoWrite *write = ioFdWriteNew(name, pipeRead[1], 5000);
ioWriteOpen(write);
ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_LOCAL_STR, read, write);
protocolServerProcess(server, NULL, hrnProtocolStatic.localHandlerList, hrnProtocolStatic.localHandlerListSize);
// Exit when done
exit(0);
}
// Close the unused file descriptors
close(pipeRead[1]);
close(pipeWrite[0]);
// Create protocol object
IoRead *read = ioFdReadNew(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol read", processId), pipeRead[0], 5000);
ioReadOpen(read);
IoWrite *write = ioFdWriteNew(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol write", processId), pipeWrite[1], 5000);
ioWriteOpen(write);
helper->client = protocolClientNew(
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol", processId), PROTOCOL_SERVICE_LOCAL_STR, read, write);
FUNCTION_HARNESS_RETURN_VOID();
}
// Else call the base function
else
protocolLocalExec_SHIMMED(helper, protocolStorageType, hostIdx, processId);
}
/**********************************************************************************************************************************/
void
hrnProtocolLocalShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM_P(VOID, handlerList);
FUNCTION_HARNESS_PARAM(UINT, handlerListSize);
FUNCTION_HARNESS_END();
hrnProtocolStatic.localHandler = true;
hrnProtocolStatic.localHandlerList = handlerList;
hrnProtocolStatic.localHandlerListSize = handlerListSize;
FUNCTION_HARNESS_RETURN_VOID();
}

View File

@ -0,0 +1,12 @@
/***********************************************************************************************************************************
Harness for Protocol Testing
***********************************************************************************************************************************/
#include "protocol/server.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Initialize the shim that allows protocalLocalGet() to start a local in a forked process rather than being exec'd. The main
// benefit is that code running in the forked process will be included in coverage so no separate tests for the local protocol
// functions should be required. A side benefit is that the pgbackrest binary does not need to be built since there is no exec.
void hrnProtocolLocalShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize);

View File

@ -4,9 +4,7 @@ Test Backup Command
#include "command/stanza/create.h" #include "command/stanza/create.h"
#include "command/stanza/upgrade.h" #include "command/stanza/upgrade.h"
#include "common/crypto/hash.h" #include "common/crypto/hash.h"
#include "common/io/bufferRead.h"
#include "common/io/bufferWrite.h" #include "common/io/bufferWrite.h"
#include "common/io/io.h"
#include "postgres/interface/static.vendor.h" #include "postgres/interface/static.vendor.h"
#include "storage/helper.h" #include "storage/helper.h"
#include "storage/posix/storage.h" #include "storage/posix/storage.h"
@ -14,6 +12,7 @@ Test Backup Command
#include "common/harnessConfig.h" #include "common/harnessConfig.h"
#include "common/harnessPostgres.h" #include "common/harnessPostgres.h"
#include "common/harnessPq.h" #include "common/harnessPq.h"
#include "common/harnessProtocol.h"
#include "common/harnessStorage.h" #include "common/harnessStorage.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -443,19 +442,15 @@ testRun(void)
{ {
FUNCTION_HARNESS_VOID(); FUNCTION_HARNESS_VOID();
// Install local command handler shim
static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_BACKUP_LIST};
hrnProtocolLocalShimInstall(testLocalHandlerList, PROTOCOL_SERVER_HANDLER_LIST_SIZE(testLocalHandlerList));
// The tests expect the timezone to be UTC // The tests expect the timezone to be UTC
setenv("TZ", "UTC", true); setenv("TZ", "UTC", true);
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true); Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
// Start a protocol server to test the protocol directly
Buffer *serverWrite = bufNew(8192);
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
ioWriteOpen(serverWriteIo);
ProtocolServer *server = protocolServerNew(strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
bufUsedSet(serverWrite, 0);
const String *pgFile = strNew("testfile"); const String *pgFile = strNew("testfile");
const String *missingFile = strNew("missing"); const String *missingFile = strNew("missing");
const String *backupLabel = strNew("20190718-155825F"); const String *backupLabel = strNew("20190718-155825F");
@ -471,7 +466,7 @@ testRun(void)
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("backupFile() and backupFileProtocol()")) if (testBegin("backupFile()"))
{ {
// Load Parameters // Load Parameters
StringList *argList = strLstNew(); StringList *argList = strLstNew();
@ -495,29 +490,6 @@ testRun(void)
TEST_RESULT_UINT(result.copySize + result.repoSize, 0, " copy/repo size 0"); TEST_RESULT_UINT(result.copySize + result.repoSize, 0, " copy/repo size 0");
TEST_RESULT_UINT(result.backupCopyResult, backupCopyResultSkip, " skip file"); TEST_RESULT_UINT(result.backupCopyResult, backupCopyResultSkip, " skip file");
// Check protocol function directly
// -------------------------------------------------------------------------------------------------------------------------
// NULL, zero param values, ignoreMissing=true
varLstAdd(paramList, varNewStr(missingFile)); // pgFile
varLstAdd(paramList, varNewBool(true)); // pgFileIgnoreMissing
varLstAdd(paramList, varNewUInt64(0)); // pgFileSize
varLstAdd(paramList, varNewBool(true)); // pgFileCopyExactSize
varLstAdd(paramList, NULL); // pgFileChecksum
varLstAdd(paramList, varNewBool(false)); // pgFileChecksumPage
varLstAdd(paramList, varNewUInt64(0)); // pgFileChecksumPageLsnLimit
varLstAdd(paramList, varNewStr(missingFile)); // repoFile
varLstAdd(paramList, varNewBool(false)); // repoFileHasReference
varLstAdd(paramList, varNewUInt(compressTypeNone)); // repoFileCompress
varLstAdd(paramList, varNewInt(0)); // repoFileCompressLevel
varLstAdd(paramList, varNewStr(backupLabel)); // backupLabel
varLstAdd(paramList, varNewBool(false)); // delta
varLstAdd(paramList, varNewUInt64(cipherTypeNone)); // cipherType
varLstAdd(paramList, NULL); // cipherSubPass
TEST_RESULT_VOID(backupFileProtocol(paramList, server), "protocol backup file - skip");
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":[3,0,0,null,null]}\n", " check result");
bufUsedSet(serverWrite, 0);
// Pg file missing - ignoreMissing=false // Pg file missing - ignoreMissing=false
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR_FMT( TEST_ERROR_FMT(
@ -578,9 +550,9 @@ testRun(void)
varBool(kvGet(result.pageChecksumResult, VARSTRDEF("valid"))), false, " pageChecksumResult valid=false"); varBool(kvGet(result.pageChecksumResult, VARSTRDEF("valid"))), false, " pageChecksumResult valid=false");
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite(), backupPathFile), " remove repo file"); TEST_RESULT_VOID(storageRemoveP(storageRepoWrite(), backupPathFile), " remove repo file");
// Check protocol function directly
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
// pgFileSize, ignoreMissing=false, backupLabel, pgFileChecksumPage, pgFileChecksumPageLsnLimit TEST_TITLE("pgFileSize, ignoreMissing=false, backupLabel, pgFileChecksumPage, pgFileChecksumPageLsnLimit");
paramList = varLstNew(); paramList = varLstNew();
varLstAdd(paramList, varNewStr(pgFile)); // pgFile varLstAdd(paramList, varNewStr(pgFile)); // pgFile
varLstAdd(paramList, varNewBool(false)); // pgFileIgnoreMissing varLstAdd(paramList, varNewBool(false)); // pgFileIgnoreMissing
@ -598,12 +570,19 @@ testRun(void)
varLstAdd(paramList, varNewUInt64(cipherTypeNone)); // cipherType varLstAdd(paramList, varNewUInt64(cipherTypeNone)); // cipherType
varLstAdd(paramList, NULL); // cipherSubPass varLstAdd(paramList, NULL); // cipherSubPass
TEST_RESULT_VOID(backupFileProtocol(paramList, server), "protocol backup file - pageChecksum"); TEST_ASSIGN(
TEST_RESULT_STR_Z( result,
strNewBuf(serverWrite), backupFile(
"{\"out\":[1,12,12,\"c3ae4687ea8ccd47bfdb190dbe7fd3b37545fdb9\",{\"align\":false,\"valid\":false}]}\n", pgFile, false, 8, false, NULL, true, 0xFFFFFFFFFFFFFFFF, pgFile, false, compressTypeNone, 1, backupLabel, false,
" check result"); cipherTypeNone, NULL),
bufUsedSet(serverWrite, 0); "backup file");
TEST_RESULT_UINT(result.copySize, 12, "copy size");
TEST_RESULT_UINT(result.repoSize, 12, "repo size");
TEST_RESULT_UINT(result.backupCopyResult, backupCopyResultCopy, "copy file");
TEST_RESULT_STR_Z(result.copyChecksum, "c3ae4687ea8ccd47bfdb190dbe7fd3b37545fdb9", "checksum");
TEST_RESULT_STR_Z(jsonFromKv(result.pageChecksumResult), "{\"align\":false,\"valid\":false}", "page checksum");
TEST_STORAGE_EXISTS(storageRepo(), strZ(backupPathFile));
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
// File exists in repo and db, checksum match, delta set, ignoreMissing false, hasReference - NOOP // File exists in repo and db, checksum match, delta set, ignoreMissing false, hasReference - NOOP
@ -621,31 +600,6 @@ testRun(void)
storageExistsP(storageRepo(), backupPathFile) && result.pageChecksumResult == NULL), storageExistsP(storageRepo(), backupPathFile) && result.pageChecksumResult == NULL),
true, " noop"); true, " noop");
// Check protocol function directly
// -------------------------------------------------------------------------------------------------------------------------
// pgFileChecksum, hasReference, delta
paramList = varLstNew();
varLstAdd(paramList, varNewStr(pgFile)); // pgFile
varLstAdd(paramList, varNewBool(false)); // pgFileIgnoreMissing
varLstAdd(paramList, varNewUInt64(12)); // pgFileSize
varLstAdd(paramList, varNewBool(false)); // pgFileCopyExactSize
varLstAdd(paramList, varNewStrZ("c3ae4687ea8ccd47bfdb190dbe7fd3b37545fdb9")); // pgFileChecksum
varLstAdd(paramList, varNewBool(false)); // pgFileChecksumPage
varLstAdd(paramList, varNewUInt64(0)); // pgFileChecksumPageLsnLimit
varLstAdd(paramList, varNewStr(pgFile)); // repoFile
varLstAdd(paramList, varNewBool(true)); // repoFileHasReference
varLstAdd(paramList, varNewUInt(compressTypeNone)); // repoFileCompress
varLstAdd(paramList, varNewInt(1)); // repoFileCompressLevel
varLstAdd(paramList, varNewStr(backupLabel)); // backupLabel
varLstAdd(paramList, varNewBool(true)); // delta
varLstAdd(paramList, varNewUInt64(cipherTypeNone)); // cipherType
varLstAdd(paramList, NULL); // cipherSubPass
TEST_RESULT_VOID(backupFileProtocol(paramList, server), "protocol backup file - noop");
TEST_RESULT_STR_Z(
strNewBuf(serverWrite), "{\"out\":[4,12,0,\"c3ae4687ea8ccd47bfdb190dbe7fd3b37545fdb9\",null]}\n", " check result");
bufUsedSet(serverWrite, 0);
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
// File exists in repo and db, pg checksum mismatch, delta set, ignoreMissing false, hasReference - COPY // File exists in repo and db, pg checksum mismatch, delta set, ignoreMissing false, hasReference - COPY
TEST_ASSIGN( TEST_ASSIGN(
@ -763,31 +717,6 @@ testRun(void)
result.pageChecksumResult == NULL), result.pageChecksumResult == NULL),
true, " compressed repo file matches"); true, " compressed repo file matches");
// Check protocol function directly
// -------------------------------------------------------------------------------------------------------------------------
// compression
paramList = varLstNew();
varLstAdd(paramList, varNewStr(pgFile)); // pgFile
varLstAdd(paramList, varNewBool(false)); // pgFileIgnoreMissing
varLstAdd(paramList, varNewUInt64(9)); // pgFileSize
varLstAdd(paramList, varNewBool(true)); // pgFileCopyExactSize
varLstAdd(paramList, varNewStrZ("9bc8ab2dda60ef4beed07d1e19ce0676d5edde67")); // pgFileChecksum
varLstAdd(paramList, varNewBool(false)); // pgFileChecksumPage
varLstAdd(paramList, varNewUInt64(0)); // pgFileChecksumPageLsnLimit
varLstAdd(paramList, varNewStr(pgFile)); // repoFile
varLstAdd(paramList, varNewBool(false)); // repoFileHasReference
varLstAdd(paramList, varNewUInt(compressTypeGz)); // repoFileCompress
varLstAdd(paramList, varNewInt(3)); // repoFileCompressLevel
varLstAdd(paramList, varNewStr(backupLabel)); // backupLabel
varLstAdd(paramList, varNewBool(false)); // delta
varLstAdd(paramList, varNewUInt64(cipherTypeNone)); // cipherType
varLstAdd(paramList, NULL); // cipherSubPass
TEST_RESULT_VOID(backupFileProtocol(paramList, server), "protocol backup file - copy, compress");
TEST_RESULT_STR_Z(
strNewBuf(serverWrite), "{\"out\":[0,9,29,\"9bc8ab2dda60ef4beed07d1e19ce0676d5edde67\",null]}\n", " check result");
bufUsedSet(serverWrite, 0);
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
// Create a zero sized file - checksum will be set but in backupManifestUpdate it will not be copied // Create a zero sized file - checksum will be set but in backupManifestUpdate it will not be copied
storagePutP(storageNewWriteP(storagePgWrite(), strNew("zerofile")), BUFSTRDEF("")); storagePutP(storageNewWriteP(storagePgWrite(), strNew("zerofile")), BUFSTRDEF(""));
@ -878,30 +807,23 @@ testRun(void)
storageExistsP(storageRepo(), backupPathFile) && result.pageChecksumResult == NULL), storageExistsP(storageRepo(), backupPathFile) && result.pageChecksumResult == NULL),
true, " recopy file to encrypted repo success"); true, " recopy file to encrypted repo success");
// Check protocol function directly
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
// cipherType, cipherPass TEST_TITLE("recopy, encrypt");
paramList = varLstNew();
varLstAdd(paramList, varNewStr(pgFile)); // pgFile
varLstAdd(paramList, varNewBool(false)); // pgFileIgnoreMissing
varLstAdd(paramList, varNewUInt64(9)); // pgFileSize
varLstAdd(paramList, varNewBool(true)); // pgFileCopyExactSize
varLstAdd(paramList, varNewStrZ("1234567890123456789012345678901234567890")); // pgFileChecksum
varLstAdd(paramList, varNewBool(false)); // pgFileChecksumPage
varLstAdd(paramList, varNewUInt64(0)); // pgFileChecksumPageLsnLimit
varLstAdd(paramList, varNewStr(pgFile)); // repoFile
varLstAdd(paramList, varNewBool(false)); // repoFileHasReference
varLstAdd(paramList, varNewUInt(compressTypeNone)); // repoFileCompress
varLstAdd(paramList, varNewInt(0)); // repoFileCompressLevel
varLstAdd(paramList, varNewStr(backupLabel)); // backupLabel
varLstAdd(paramList, varNewBool(false)); // delta
varLstAdd(paramList, varNewUInt64(cipherTypeAes256Cbc));// cipherType
varLstAdd(paramList, varNewStrZ("12345678")); // cipherPass
TEST_RESULT_VOID(backupFileProtocol(paramList, server), "protocol backup file - recopy, encrypt"); TEST_ASSIGN(
TEST_RESULT_STR_Z( result,
strNewBuf(serverWrite), "{\"out\":[2,9,32,\"9bc8ab2dda60ef4beed07d1e19ce0676d5edde67\",null]}\n", " check result"); backupFile(
bufUsedSet(serverWrite, 0); pgFile, false, 9, true, strNew("1234567890123456789012345678901234567890"), false, 0, pgFile, false,
compressTypeNone, 0, backupLabel, false, cipherTypeAes256Cbc, strNew("12345678")),
"backup file");
TEST_RESULT_UINT(result.copySize, 9, " copy size set");
TEST_RESULT_UINT(result.repoSize, 32, " repo size set");
TEST_RESULT_UINT(result.backupCopyResult, backupCopyResultReCopy, " recopy file");
TEST_RESULT_BOOL(
(strEqZ(result.copyChecksum, "9bc8ab2dda60ef4beed07d1e19ce0676d5edde67") &&
storageExistsP(storageRepo(), backupPathFile) && result.pageChecksumResult == NULL),
true, " recopy file to encrypted repo success");
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************

View File

@ -3,9 +3,6 @@ Test Restore Command
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/compress/helper.h" #include "common/compress/helper.h"
#include "common/crypto/cipherBlock.h" #include "common/crypto/cipherBlock.h"
#include "common/io/io.h"
#include "common/io/bufferRead.h"
#include "common/io/bufferWrite.h"
#include "postgres/version.h" #include "postgres/version.h"
#include "storage/posix/storage.h" #include "storage/posix/storage.h"
#include "storage/helper.h" #include "storage/helper.h"
@ -13,6 +10,7 @@ Test Restore Command
#include "common/harnessConfig.h" #include "common/harnessConfig.h"
#include "common/harnessInfo.h" #include "common/harnessInfo.h"
#include "common/harnessPostgres.h" #include "common/harnessPostgres.h"
#include "common/harnessProtocol.h"
#include "common/harnessStorage.h" #include "common/harnessStorage.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -148,6 +146,10 @@ testRun(void)
{ {
FUNCTION_HARNESS_VOID(); FUNCTION_HARNESS_VOID();
// Install local command handler shim
static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_RESTORE_LIST};
hrnProtocolLocalShimInstall(testLocalHandlerList, PROTOCOL_SERVER_HANDLER_LIST_SIZE(testLocalHandlerList));
// Create default storage object for testing // Create default storage object for testing
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true); Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
@ -158,16 +160,6 @@ testRun(void)
const String *repoFile1 = strNew("pg_data/testfile"); const String *repoFile1 = strNew("pg_data/testfile");
unsigned int repoIdx = 0; unsigned int repoIdx = 0;
// Start a protocol server to test the protocol directly
Buffer *serverWrite = bufNew(8192);
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
ioWriteOpen(serverWriteIo);
ProtocolServer *server = protocolServerNew(
strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
bufUsedSet(serverWrite, 0);
// Load Parameters // Load Parameters
StringList *argList = strLstNew(); StringList *argList = strLstNew();
strLstAddZ(argList, "--stanza=test1"); strLstAddZ(argList, "--stanza=test1");
@ -330,62 +322,6 @@ testRun(void)
strNew("9bc8ab2dda60ef4beed07d1e19ce0676d5edde67"), false, 0, 1557432154, 0600, strNew(testUser()), strNew("9bc8ab2dda60ef4beed07d1e19ce0676d5edde67"), false, 0, 1557432154, 0600, strNew(testUser()),
strNew(testGroup()), 0, true, false, NULL), strNew(testGroup()), 0, true, false, NULL),
false, "sha1 delta existing, content differs"); false, "sha1 delta existing, content differs");
// Check protocol function directly
// -------------------------------------------------------------------------------------------------------------------------
VariantList *paramList = varLstNew();
varLstAdd(paramList, varNewStr(repoFile1));
varLstAdd(paramList, varNewUInt(repoIdx));
varLstAdd(paramList, varNewStr(repoFileReferenceFull));
varLstAdd(paramList, varNewUInt(compressTypeNone));
varLstAdd(paramList, varNewStrZ("protocol"));
varLstAdd(paramList, varNewStrZ("9bc8ab2dda60ef4beed07d1e19ce0676d5edde67"));
varLstAdd(paramList, varNewBool(false));
varLstAdd(paramList, varNewUInt64(9));
varLstAdd(paramList, varNewUInt64(1557432100));
varLstAdd(paramList, varNewStrZ("0677"));
varLstAdd(paramList, varNewStrZ(testUser()));
varLstAdd(paramList, varNewStrZ(testGroup()));
varLstAdd(paramList, varNewUInt64(1557432200));
varLstAdd(paramList, varNewBool(false));
varLstAdd(paramList, varNewBool(false));
varLstAdd(paramList, NULL);
TEST_RESULT_VOID(restoreFileProtocol(paramList, server), "protocol restore file");
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":true}\n", " check result");
bufUsedSet(serverWrite, 0);
info = storageInfoP(storagePg(), strNew("protocol"));
TEST_RESULT_BOOL(info.exists, true, " check exists");
TEST_RESULT_UINT(info.size, 9, " check size");
TEST_RESULT_UINT(info.mode, 0677, " check mode");
TEST_RESULT_INT(info.timeModified, 1557432100, " check time");
TEST_RESULT_STR_Z(info.user, testUser(), " check user");
TEST_RESULT_STR_Z(info.group, testGroup(), " check group");
TEST_RESULT_STR_Z(
strNewBuf(storageGetP(storageNewReadP(storagePg(), strNew("protocol")))), "atestfile", " check contents");
paramList = varLstNew();
varLstAdd(paramList, varNewStr(repoFile1));
varLstAdd(paramList, varNewUInt(repoIdx));
varLstAdd(paramList, varNewStr(repoFileReferenceFull));
varLstAdd(paramList, varNewUInt(compressTypeNone));
varLstAdd(paramList, varNewStrZ("protocol"));
varLstAdd(paramList, varNewStrZ("9bc8ab2dda60ef4beed07d1e19ce0676d5edde67"));
varLstAdd(paramList, varNewBool(false));
varLstAdd(paramList, varNewUInt64(9));
varLstAdd(paramList, varNewUInt64(1557432100));
varLstAdd(paramList, varNewStrZ("0677"));
varLstAdd(paramList, varNewStrZ(testUser()));
varLstAdd(paramList, varNewStrZ(testGroup()));
varLstAdd(paramList, varNewUInt64(1557432200));
varLstAdd(paramList, varNewBool(true));
varLstAdd(paramList, varNewBool(false));
varLstAdd(paramList, NULL);
TEST_RESULT_VOID(restoreFileProtocol(paramList, server), "protocol restore file");
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":false}\n", " check result");
bufUsedSet(serverWrite, 0);
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@ -2741,7 +2677,7 @@ testRun(void)
TEST_ERROR_FMT( TEST_ERROR_FMT(
cmdRestore(), FileMissingError, cmdRestore(), FileMissingError,
"raised from local-1 protocol: unable to open missing file" "raised from local-1 shim protocol: unable to open missing file"
" '%s/repo/backup/test1/20161219-212741F_20161219-212918I/pg_data/global/pg_control' for read", " '%s/repo/backup/test1/20161219-212741F_20161219-212918I/pg_data/global/pg_control' for read",
testPath()); testPath());

View File

@ -2,7 +2,6 @@
Test Stanza Commands Test Stanza Commands
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#include "common/io/bufferRead.h" #include "common/io/bufferRead.h"
#include "common/io/bufferWrite.h"
#include "postgres/interface.h" #include "postgres/interface.h"
#include "postgres/version.h" #include "postgres/version.h"
#include "storage/posix/storage.h" #include "storage/posix/storage.h"
@ -12,6 +11,8 @@ Test Stanza Commands
#include "common/harnessPostgres.h" #include "common/harnessPostgres.h"
#include "common/harnessPq.h" #include "common/harnessPq.h"
#include "common/harnessProtocol.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Test Run Test Run
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -20,6 +21,10 @@ testRun(void)
{ {
FUNCTION_HARNESS_VOID(); FUNCTION_HARNESS_VOID();
// Install local command handler shim
static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_VERIFY_LIST};
hrnProtocolLocalShimInstall(testLocalHandlerList, PROTOCOL_SERVER_HANDLER_LIST_SIZE(testLocalHandlerList));
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true); Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
String *stanza = strNew("db"); String *stanza = strNew("db");
@ -877,7 +882,7 @@ testRun(void)
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("verifyFile() and verifyFileProtocol()")) if (testBegin("verifyFile()"))
{ {
// Load Parameters // Load Parameters
StringList *argList = strLstDup(argListBase); StringList *argList = strLstDup(argListBase);
@ -911,26 +916,6 @@ testRun(void)
verifyFile( verifyFile(
filePathName, strNew("badchecksum"), fileSize, strNew("pass")), verifyChecksumMismatch, filePathName, strNew("badchecksum"), fileSize, strNew("pass")), verifyChecksumMismatch,
"file encrypted compressed checksum mismatch"); "file encrypted compressed checksum mismatch");
//--------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("verifyFileProtocol()");
// Start a protocol server to test the protocol directly
Buffer *serverWrite = bufNew(8192);
IoWrite *serverWriteIo = ioBufferWriteNew(serverWrite);
ioWriteOpen(serverWriteIo);
ProtocolServer *server = protocolServerNew(strNew("test"), strNew("test"), ioBufferReadNew(bufNew(0)), serverWriteIo);
bufUsedSet(serverWrite, 0);
VariantList *paramList = varLstNew();
varLstAdd(paramList, varNewStr(filePathName));
varLstAdd(paramList, varNewStr(fileChecksum));
varLstAdd(paramList, varNewUInt64(fileSize));
varLstAdd(paramList, varNewStrZ("pass"));
TEST_RESULT_VOID(verifyFileProtocol(paramList, server), "protocol verify file");
TEST_RESULT_STR_Z(strNewBuf(serverWrite), "{\"out\":0}\n", "check result");
bufUsedSet(serverWrite, 0);
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@ -1271,7 +1256,7 @@ testRun(void)
"'11-2/0000000200000007/000000020000000700000FFF-ee161f898c9012dd0c28b3fd1e7140b9cf411306'\n" "'11-2/0000000200000007/000000020000000700000FFF-ee161f898c9012dd0c28b3fd1e7140b9cf411306'\n"
"P01 ERROR: [039]: invalid result " "P01 ERROR: [039]: invalid result "
"11-2/0000000200000008/000000020000000800000003-656817043007aa2100c44c712bcb456db705dab9: [41] raised from " "11-2/0000000200000008/000000020000000800000003-656817043007aa2100c44c712bcb456db705dab9: [41] raised from "
"local-1 protocol: unable to open file " "local-1 shim protocol: unable to open file "
"'%s/%s/11-2/0000000200000008/000000020000000800000003-656817043007aa2100c44c712bcb456db705dab9' for read: " "'%s/%s/11-2/0000000200000008/000000020000000800000003-656817043007aa2100c44c712bcb456db705dab9' for read: "
"[13] Permission denied\n" "[13] Permission denied\n"
"P00 WARN: unable to open missing file '%s/%s/20181119-152800F/backup.manifest' for read\n" "P00 WARN: unable to open missing file '%s/%s/20181119-152800F/backup.manifest' for read\n"
@ -1283,8 +1268,8 @@ testRun(void)
"P01 ERROR: [028]: file missing '20181119-152900F_20181119-152909D/pg_data/testmissing'\n" "P01 ERROR: [028]: file missing '20181119-152900F_20181119-152909D/pg_data/testmissing'\n"
"P00 WARN: unable to open missing file '%s/%s/20181119-153000F/backup.manifest' for read\n" "P00 WARN: unable to open missing file '%s/%s/20181119-153000F/backup.manifest' for read\n"
"P00 INFO: backup '20181119-153000F' appears to be in progress, skipping\n" "P00 INFO: backup '20181119-153000F' appears to be in progress, skipping\n"
"P01 ERROR: [039]: invalid result UNPROCESSEDBACKUP/pg_data/testother: [41] raised from local-1 protocol: unable " "P01 ERROR: [039]: invalid result UNPROCESSEDBACKUP/pg_data/testother: [41] raised from local-1 shim protocol:"
"to open file '%s/%s/UNPROCESSEDBACKUP/pg_data/testother' for read: [13] Permission denied\n" " unable to open file '%s/%s/UNPROCESSEDBACKUP/pg_data/testother' for read: [13] Permission denied\n"
"P00 DETAIL: archiveId: 11-2, wal start: 000000020000000700000FFD, wal stop: 000000020000000800000000\n" "P00 DETAIL: archiveId: 11-2, wal start: 000000020000000700000FFD, wal stop: 000000020000000800000000\n"
"P00 DETAIL: archiveId: 11-2, wal start: 000000020000000800000002, wal stop: 000000020000000800000003\n" "P00 DETAIL: archiveId: 11-2, wal start: 000000020000000800000002, wal stop: 000000020000000800000003\n"
"P00 DETAIL: archiveId: 11-2, wal start: 000000030000000000000000, wal stop: 000000030000000000000001\n" "P00 DETAIL: archiveId: 11-2, wal start: 000000030000000000000000, wal stop: 000000030000000000000001\n"