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"); hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
HRN_CFG_LOAD(cfgCmdBackup, argList); HRN_CFG_LOAD(cfgCmdBackup, argList);
const Storage *const storagePg = storagePgGet(1, false);
const Storage *const storagePgWrite = storagePgGet(1, true); const Storage *const storagePgWrite = storagePgGet(1, true);
// Load configuration and get repo remote storage // Load configuration and get repo remote storage
@ -89,7 +90,7 @@ testRun(void)
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("storageInterface(), storageFeature, and storagePathP()")) 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_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(storageRepo, NULL), TEST_PATH "/repo128", "check repo path");
TEST_RESULT_STR_Z(storagePathP(storageRepoWrite, NULL), TEST_PATH "/repo128", "check repo write 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)"); TEST_TITLE("write file, free before close, make sure the .tmp file remains (interleaved with normal write)");
StorageWrite *write3 = NULL; StorageWrite *write3 = NULL;
TEST_ASSIGN(write, storageNewWriteP(storageRepoWrite, STRDEF("test2.txt")), "new write file"); TEST_ASSIGN(write, storageNewWriteP(storagePgWrite, STRDEF("test2.txt")), "new write file");
TEST_ASSIGN(write3, storageNewWriteP(storageRepoWrite, STRDEF("test3.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(write)), "open file");
TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(write3)), "open file 3"); 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_VOID(ioWriteClose(storageWriteIo(write3)), "close file 3");
TEST_RESULT_UINT( TEST_RESULT_UINT(
storageInfoP(storageTest, STRDEF("repo128/test2.txt.pgbackrest.tmp")).size, 16384, "file exists and is partial"); storageInfoP(storageTest, STRDEF("pg256/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"); TEST_RESULT_BOOL(bufEq(storageGetP(storageNewReadP(storagePg, STRDEF("test3.txt"))), contentBuf), true, "check file 3");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("write free and close before write"); TEST_TITLE("write free and close before write");
@ -520,10 +521,10 @@ testRun(void)
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("create path via the remote"); TEST_TITLE("create path via the remote");
// Check the repo via the local test storage to ensure the remote created it. // Check pg via the local test storage to ensure the remote created it.
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, path), "new path"); TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, path), "new path");
StorageInfo info = {0}; 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_BOOL(info.exists, true, "path exists");
TEST_RESULT_INT(info.mode, STORAGE_MODE_PATH_DEFAULT, "mode is default"); 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_TITLE("error on existing path");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageRepoWrite, STRDEF("testpath"), .errorOnExists = true), PathCreateError, storagePathCreateP(storagePgWrite, STRDEF("testpath"), .errorOnExists = true), PathCreateError,
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/repo128/testpath': [17] File exists"); "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_TITLE("error on missing parent path");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageRepoWrite, STRDEF("parent/testpath"), .noParentCreate = true), PathCreateError, storagePathCreateP(storagePgWrite, STRDEF("parent/testpath"), .noParentCreate = true), PathCreateError,
"raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/repo128/parent/testpath': [2] No such" "raised from remote-0 shim protocol: unable to create path '" TEST_PATH "/pg256/parent/testpath': [2] No such"
" file or directory"); " file or directory");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("create parent/path with non-default mode"); 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( TEST_STORAGE_LIST(
storageRepo, TEST_PATH "/repo128/parent", storagePg, TEST_PATH "/pg256/parent",
"./ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n" "./ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n"
"testpath/ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n", "testpath/ {u=" TEST_USER ", g=" TEST_GROUP ", m=0777}\n",
.level = storageInfoLevelDetail, .includeDot = true); .level = storageInfoLevelDetail, .includeDot = true);
@ -614,11 +615,11 @@ testRun(void)
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("storagePathSync()")) if (testBegin("storagePathSync()"))
{ {
storagePathCreateP(storageTest, STRDEF("repo128")); storagePathCreateP(storageTest, STRDEF("pg256"));
const String *path = STRDEF("testpath"); const String *path = STRDEF("testpath");
TEST_RESULT_VOID(storagePathCreateP(storageRepoWrite, path), "new path"); TEST_RESULT_VOID(storagePathCreateP(storagePgWrite, path), "new path");
TEST_RESULT_VOID(storagePathSyncP(storageRepoWrite, path), "sync path"); TEST_RESULT_VOID(storagePathSyncP(storagePgWrite, path), "sync path");
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@ -627,122 +628,122 @@ testRun(void)
StorageInfo info = {0}; StorageInfo info = {0};
const String *path = STRDEF("20181119-152138F"); const String *path = STRDEF("20181119-152138F");
const String *latestLabel = STRDEF("latest"); 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"); TEST_TITLE("create/remove symlink to path and to file");
// Create the path and symlink via the remote // 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( TEST_RESULT_VOID(
storageLinkCreateP( 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"); "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 // 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( 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( TEST_RESULT_BOOL(
storageInfoP( 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"); "symlink to path exists");
// Verify link mapping via the local test storage // Verify link mapping via the local test storage
TEST_ASSIGN( TEST_ASSIGN(
info, 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_STR(info.linkDestination, path, "match link destination");
TEST_RESULT_INT(info.type, storageTypeLink, "check type is link"); 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( TEST_RESULT_BOOL(
storageInfoP( 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"); "symlink to path removed");
// Create a file and sym link to it via the remote, // 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( TEST_RESULT_VOID(
storageLinkCreateP( 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"); "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 // 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( 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( TEST_RESULT_BOOL(
storageInfoP( 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"); "symlink to file exists");
// Verify link mapping via the local test storage // Verify link mapping via the local test storage
TEST_ASSIGN( TEST_ASSIGN(
info, 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_STR(info.linkDestination, testFile, "match link destination");
TEST_RESULT_INT(info.type, storageTypeLink, "check type is link"); TEST_RESULT_INT(info.type, storageTypeLink, "check type is link");
// Verify file and link contents match // Verify file and link contents match
Buffer *testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("repo128/test.file"))); Buffer *testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("pg256/test.file")));
Buffer *symLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel)))); 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, BUFSTRDEF("TESTME")), true, "file contents match test buffer");
TEST_RESULT_BOOL(bufEq(testFileBuffer, symLinkBuffer), true, "symlink and file contents match each other"); 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( 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_VOID(storageRemoveP(storageRepoWrite, latestLabel), "remote remove symlink"); TEST_RESULT_VOID(storageRemoveP(storagePgWrite, latestLabel), "remote remove symlink");
TEST_RESULT_BOOL( TEST_RESULT_BOOL(
storageInfoP( 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"); "symlink to file removed");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("hardlink success/fail"); TEST_TITLE("hardlink success/fail");
// Create a file and hard link to it via the remote, // 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( TEST_RESULT_VOID(
storageLinkCreateP( 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), .linkType = storageLinkHard),
"hardlink to test file"); "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 // 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 // via remote and confirm removed
TEST_RESULT_BOOL( 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( TEST_RESULT_BOOL(
storageInfoP( 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( TEST_ASSIGN(
info, 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"); TEST_RESULT_INT(info.type, storageTypeFile, "check type is file");
// Verify file and link contents match // Verify file and link contents match
testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("repo128/test.file"))); testFileBuffer = storageGetP(storageNewReadP(storageTest, STRDEF("pg256/test.file")));
Buffer *hardLinkBuffer = storageGetP(storageNewReadP(storageTest, strNewFmt("repo128/%s", strZ(latestLabel)))); 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, 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_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(storagePgWrite, testFile), "remove test file");
TEST_RESULT_VOID(storageRemoveP(storageRepoWrite, latestLabel), "remove hard link"); TEST_RESULT_VOID(storageRemoveP(storagePgWrite, latestLabel), "remove hard link");
TEST_RESULT_BOOL( 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( TEST_RESULT_BOOL(
storageInfoP( 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 // Hard link to directory not permitted
TEST_ERROR( TEST_ERROR(
storageLinkCreateP( storageLinkCreateP(
storageRepoWrite, storagePgWrite,
strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(path)), strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(path)),
strNewFmt("%s/%s", strZ(storagePathP(storageRepo, NULL)), strZ(latestLabel)), .linkType = storageLinkHard), strNewFmt("%s/%s", strZ(storagePathP(storagePg, NULL)), strZ(latestLabel)), .linkType = storageLinkHard),
FileOpenError, FileOpenError,
"raised from remote-0 shim protocol: unable to create hardlink '" TEST_PATH "/repo128/latest' to" "raised from remote-0 shim protocol: unable to create hardlink '" TEST_PATH "/pg256/latest' to"
" '" TEST_PATH "/repo128/20181119-152138F': [1] Operation not permitted"); " '" 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 // When clients are freed by protocolClientFree() they do not wait for a response. We need to wait for a response here to be