1
0
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:
David Steele
2024-08-30 16:00:07 +07:00
parent b3fed2cfcf
commit 3b3886f3b8

View File

@ -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