You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-07 00:35:37 +02:00
Refactor storage/remote module to move repository storage tests.
Move tests that use functions that are not valid for non-Posix repositories to pg storage. This allows for a test storage driver that only implements functions required for repositories.
This commit is contained in:
@ -61,6 +61,7 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
|
||||
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||
|
||||
const Storage *const storagePg = storagePgGet(1, false);
|
||||
const Storage *const storagePgWrite = storagePgGet(1, true);
|
||||
|
||||
// Load configuration and get repo remote storage
|
||||
@ -89,7 +90,7 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storageInterface(), storageFeature, and storagePathP()"))
|
||||
{
|
||||
TEST_RESULT_UINT(storageInterface(storageRepoWrite).feature, storageInterface(storageTest).feature, "check features");
|
||||
TEST_RESULT_UINT(storageInterface(storageRepoWrite).feature, storageInterface(storageRepo).feature, "check features");
|
||||
TEST_RESULT_BOOL(storageFeature(storageRepoWrite, storageFeaturePath), true, "check path feature");
|
||||
TEST_RESULT_STR_Z(storagePathP(storageRepo, NULL), TEST_PATH "/repo128", "check repo path");
|
||||
TEST_RESULT_STR_Z(storagePathP(storageRepoWrite, NULL), TEST_PATH "/repo128", "check repo write path");
|
||||
@ -474,8 +475,8 @@ testRun(void)
|
||||
TEST_TITLE("write file, free before close, make sure the .tmp file remains (interleaved with normal write)");
|
||||
|
||||
StorageWrite *write3 = NULL;
|
||||
TEST_ASSIGN(write, storageNewWriteP(storageRepoWrite, STRDEF("test2.txt")), "new write file");
|
||||
TEST_ASSIGN(write3, storageNewWriteP(storageRepoWrite, STRDEF("test3.txt")), "new write file");
|
||||
TEST_ASSIGN(write, storageNewWriteP(storagePgWrite, STRDEF("test2.txt")), "new write file");
|
||||
TEST_ASSIGN(write3, storageNewWriteP(storagePgWrite, STRDEF("test3.txt")), "new write file");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(write)), "open file");
|
||||
TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(write3)), "open file 3");
|
||||
@ -487,8 +488,8 @@ testRun(void)
|
||||
TEST_RESULT_VOID(ioWriteClose(storageWriteIo(write3)), "close file 3");
|
||||
|
||||
TEST_RESULT_UINT(
|
||||
storageInfoP(storageTest, STRDEF("repo128/test2.txt.pgbackrest.tmp")).size, 16384, "file exists and is partial");
|
||||
TEST_RESULT_BOOL(bufEq(storageGetP(storageNewReadP(storageRepo, STRDEF("test3.txt"))), contentBuf), true, "check file 3");
|
||||
storageInfoP(storageTest, STRDEF("pg256/test2.txt.pgbackrest.tmp")).size, 16384, "file exists and is partial");
|
||||
TEST_RESULT_BOOL(bufEq(storageGetP(storageNewReadP(storagePg, STRDEF("test3.txt"))), contentBuf), true, "check file 3");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("write free and close before write");
|
||||
@ -520,10 +521,10 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("create path via the remote");
|
||||
|
||||
// Check the repo via the local test storage to ensure the remote created it.
|
||||
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, path), "new path");
|
||||
// Check pg via the local test storage to ensure the remote created it.
|
||||
TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, path), "new path");
|
||||
StorageInfo info = {0};
|
||||
TEST_ASSIGN(info, storageInfoP(storageTest, strNewFmt("repo128/%s", strZ(path))), "get path info");
|
||||
TEST_ASSIGN(info, storageInfoP(storageTest, strNewFmt("pg256/%s", strZ(path))), "get path info");
|
||||
TEST_RESULT_BOOL(info.exists, true, "path exists");
|
||||
TEST_RESULT_INT(info.mode, STORAGE_MODE_PATH_DEFAULT, "mode is default");
|
||||
|
||||
@ -531,24 +532,24 @@ testRun(void)
|
||||
TEST_TITLE("error on existing path");
|
||||
|
||||
TEST_ERROR(
|
||||
storagePathCreateP(storageRepoWrite, STRDEF("testpath"), .errorOnExists = true), PathCreateError,
|
||||
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/repo128/testpath': [17] File exists");
|
||||
storagePathCreateP(storagePgWrite, STRDEF("testpath"), .errorOnExists = true), PathCreateError,
|
||||
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/pg256/testpath': [17] File exists");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error on missing parent path");
|
||||
|
||||
TEST_ERROR(
|
||||
storagePathCreateP(storageRepoWrite, STRDEF("parent/testpath"), .noParentCreate = true), PathCreateError,
|
||||
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/repo128/parent/testpath': [2] No such"
|
||||
storagePathCreateP(storagePgWrite, STRDEF("parent/testpath"), .noParentCreate = true), PathCreateError,
|
||||
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/pg256/parent/testpath': [2] No such"
|
||||
" file or directory");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("create parent/path with non-default mode");
|
||||
|
||||
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, STRDEF("parent/testpath"), .mode = 0777), "path create");
|
||||
TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, STRDEF("parent/testpath"), .mode = 0777), "path create");
|
||||
|
||||
TEST_STORAGE_LIST(
|
||||
storageRepo, TEST_PATH "/repo128/parent",
|
||||
storagePg, TEST_PATH "/pg256/parent",
|
||||
"./ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n"
|
||||
"testpath/ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n",
|
||||
.level = storageInfoLevelDetail, .includeDot = true);
|
||||
@ -614,11 +615,11 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("storagePathSync()"))
|
||||
{
|
||||
storagePathCreateP(storageTest, STRDEF("repo128"));
|
||||
storagePathCreateP(storageTest, STRDEF("pg256"));
|
||||
|
||||
const String *path = STRDEF("testpath");
|
||||
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, path), "new path");
|
||||
TEST_RESULT_VOID(storagePathSyncP(storageRepoWrite, path), "sync path");
|
||||
TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, path), "new path");
|
||||
TEST_RESULT_VOID(storagePathSyncP(storagePgWrite, path), "sync path");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -627,122 +628,122 @@ testRun(void)
|
||||
StorageInfo info = {0};
|
||||
const String *path = STRDEF("20181119-152138F");
|
||||
const String *latestLabel = STRDEF("latest");
|
||||
const String *testFile = strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), "test.file");
|
||||
const String *testFile = strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), "test.file");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("create/remove symlink to path and to file");
|
||||
|
||||
// Create the path and symlink via the remote
|
||||
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, path), "remote create path to link to");
|
||||
TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, path), "remote create path to link to");
|
||||
TEST_RESULT_VOID(
|
||||
storageLinkCreateP(
|
||||
storageRepoWrite, path, strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(latestLabel))),
|
||||
storagePgWrite, path, strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(latestLabel))),
|
||||
"remote create path symlink");
|
||||
|
||||
// Check the repo via the local test storage to ensure the remote wrote to it, then remove via remote and confirm removed
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(storageTest, strNewFmt("repo128/%s", strZ(path)), .ignoreMissing = true).exists, true, "path exists");
|
||||
storageInfoP(storageTest, strNewFmt("pg256/%s", strZ(path)), .ignoreMissing = true).exists, true, "path exists");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true,
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true,
|
||||
"symlink to path exists");
|
||||
|
||||
// Verify link mapping via the local test storage
|
||||
TEST_ASSIGN(
|
||||
info,
|
||||
storageInfoP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = false), "get symlink info");
|
||||
storageInfoP(storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = false), "get symlink info");
|
||||
TEST_RESULT_STR(info.linkDestination, path, "match link destination");
|
||||
TEST_RESULT_INT(info.type, storageTypeLink, "check type is link");
|
||||
|
||||
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, latestLabel), "remote remove symlink");
|
||||
TEST_RESULT_VOID(storageRemoveP(storagePgWrite, latestLabel), "remote remove symlink");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false,
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false,
|
||||
"symlink to path removed");
|
||||
|
||||
// Create a file and sym link to it via the remote,
|
||||
TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageRepoWrite, testFile), BUFSTRDEF("TESTME")), "put test file");
|
||||
TEST_RESULT_VOID(storagePutP(storageNewWriteP(storagePgWrite, testFile), BUFSTRDEF("TESTME")), "put test file");
|
||||
TEST_RESULT_VOID(
|
||||
storageLinkCreateP(
|
||||
storageRepoWrite, testFile, strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(latestLabel))),
|
||||
storagePgWrite, testFile, strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(latestLabel))),
|
||||
"remote create file symlink");
|
||||
|
||||
// Check the repo via the local test storage to ensure the remote wrote to it, then remove via remote and confirm removed
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(storageTest, strNewFmt("repo128/test.file"), .ignoreMissing = true).exists, true, "test file exists");
|
||||
storageInfoP(storageTest, strNewFmt("pg256/test.file"), .ignoreMissing = true).exists, true, "test file exists");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true,
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true,
|
||||
"symlink to file exists");
|
||||
|
||||
// Verify link mapping via the local test storage
|
||||
TEST_ASSIGN(
|
||||
info,
|
||||
storageInfoP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = false), "get symlink info");
|
||||
storageInfoP(storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = false), "get symlink info");
|
||||
TEST_RESULT_STR(info.linkDestination, testFile, "match link destination");
|
||||
TEST_RESULT_INT(info.type, storageTypeLink, "check type is link");
|
||||
|
||||
// Verify file and link contents match
|
||||
Buffer *testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("repo128/test.file")));
|
||||
Buffer *symLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel))));
|
||||
Buffer *testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("pg256/test.file")));
|
||||
Buffer *symLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("pg256/%s", strZ(latestLabel))));
|
||||
TEST_RESULT_BOOL(bufEq(testFileBuffer, BUFSTRDEF("TESTME")), true, "file contents match test buffer");
|
||||
TEST_RESULT_BOOL(bufEq(testFileBuffer, symLinkBuffer), true, "symlink and file contents match each other");
|
||||
|
||||
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, testFile), "remote remove test file");
|
||||
TEST_RESULT_VOID(storageRemoveP(storagePgWrite, testFile), "remote remove test file");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(storageTest, STRDEF("repo128/test.file"), .ignoreMissing = true).exists, false, "test file removed");
|
||||
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, latestLabel), "remote remove symlink");
|
||||
storageInfoP(storageTest, STRDEF("pg256/test.file"), .ignoreMissing = true).exists, false, "test file removed");
|
||||
TEST_RESULT_VOID(storageRemoveP(storagePgWrite, latestLabel), "remote remove symlink");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false,
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false,
|
||||
"symlink to file removed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("hardlink success/fail");
|
||||
|
||||
// Create a file and hard link to it via the remote,
|
||||
TEST_RESULT_VOID(storagePutP(storageNewWriteP(storageRepoWrite, testFile), BUFSTRDEF("TESTME")), "put test file");
|
||||
TEST_RESULT_VOID(storagePutP(storageNewWriteP(storagePgWrite, testFile), BUFSTRDEF("TESTME")), "put test file");
|
||||
TEST_RESULT_VOID(
|
||||
storageLinkCreateP(
|
||||
storageRepoWrite, testFile, strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(latestLabel)),
|
||||
storagePgWrite, testFile, strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(latestLabel)),
|
||||
.linkType = storageLinkHard),
|
||||
"hardlink to test file");
|
||||
|
||||
// Check the repo via the local test storage to ensure the remote wrote to it, check that files and link match, then remove
|
||||
// via remote and confirm removed
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(storageTest, STRDEF("repo128/test.file"), .ignoreMissing = true).exists, true, "test file exists");
|
||||
storageInfoP(storageTest, STRDEF("pg256/test.file"), .ignoreMissing = true).exists, true, "test file exists");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true, "hard link exists");
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, true, "hard link exists");
|
||||
TEST_ASSIGN(
|
||||
info,
|
||||
storageInfoP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = false), "get hard link info");
|
||||
storageInfoP(storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = false), "get hard link info");
|
||||
TEST_RESULT_INT(info.type, storageTypeFile, "check type is file");
|
||||
|
||||
// Verify file and link contents match
|
||||
testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("repo128/test.file")));
|
||||
Buffer *hardLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel))));
|
||||
testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("pg256/test.file")));
|
||||
Buffer *hardLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("pg256/%s", strZ(latestLabel))));
|
||||
TEST_RESULT_BOOL(bufEq(testFileBuffer, BUFSTRDEF("TESTME")), true, "file contents match test buffer");
|
||||
TEST_RESULT_BOOL(bufEq(testFileBuffer, hardLinkBuffer), true, "hard link and file contents match each other");
|
||||
|
||||
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, testFile), "remove test file");
|
||||
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, latestLabel), "remove hard link");
|
||||
TEST_RESULT_VOID(storageRemoveP(storagePgWrite, testFile), "remove test file");
|
||||
TEST_RESULT_VOID(storageRemoveP(storagePgWrite, latestLabel), "remove hard link");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(storageTest, STRDEF("repo128/test.file"), .ignoreMissing = true).exists, false, "test file removed");
|
||||
storageInfoP(storageTest, STRDEF("pg256/test.file"), .ignoreMissing = true).exists, false, "test file removed");
|
||||
TEST_RESULT_BOOL(
|
||||
storageInfoP(
|
||||
storageTest, strNewFmt("repo128/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false, "hard link removed");
|
||||
storageTest, strNewFmt("pg256/%s", strZ(latestLabel)), .ignoreMissing = true).exists, false, "hard link removed");
|
||||
|
||||
// Hard link to directory not permitted
|
||||
TEST_ERROR(
|
||||
storageLinkCreateP(
|
||||
storageRepoWrite,
|
||||
strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(path)),
|
||||
strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(latestLabel)), .linkType = storageLinkHard),
|
||||
storagePgWrite,
|
||||
strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(path)),
|
||||
strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(latestLabel)), .linkType = storageLinkHard),
|
||||
FileOpenError,
|
||||
"raised from remote-0 shim protocol: unable to create hardlink '" TEST_PATH "/repo128/latest' to"
|
||||
" '" TEST_PATH "/repo128/20181119-152138F': [1] Operation not permitted");
|
||||
"raised from remote-0 shim protocol: unable to create hardlink '" TEST_PATH "/pg256/latest' to"
|
||||
" '" TEST_PATH "/pg256/20181119-152138F': [1] Operation not permitted");
|
||||
}
|
||||
|
||||
// When clients are freed by protocolClientFree() they do not wait for a response. We need to wait for a response here to be
|
||||
|
Reference in New Issue
Block a user