Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/command/repo/push.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ storagePushProcess(const String *file, CompressType compressType, int compressLe
IoFilterGroup *const writeFilterGroup = ioWriteFilterGroup(destinationIo);

const String *manifestFileName = strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strZ(backupLabel));
Manifest *manifest = manifestLoadFile(
storage, manifestFileName,
cipherTypeNone, NULL);
const String *manifestFileNameCopy = strNewFmt("%s" INFO_COPY_EXT, strZ(manifestFileName));

// Load main manifest only. Don't fallback to copy. So resumable backup cannot be made to appear complete.
Manifest *manifest = manifestNewLoad(storageReadIo(storageNewReadP(storage, manifestFileName)));

// Add SHA1 filter
ioFilterGroupAdd(writeFilterGroup, cryptoHashNew(hashTypeSha1));
Expand Down Expand Up @@ -151,6 +152,7 @@ storagePushProcess(const String *file, CompressType compressType, int compressLe
manifestFile.sizeRepo = customFile.sizeRepo;
manifestFile.timestamp = customFile.timestamp;
manifestFile.checksumSha1 = customFile.checksumSha1;
manifestFile.checksumRepoSha1 = customFile.checksumRepoSha1;

manifestCustomFileUpdate(manifest, &manifestFile);
found = true;
Expand All @@ -161,14 +163,18 @@ storagePushProcess(const String *file, CompressType compressType, int compressLe
if (!found)
manifestCustomFileAdd(manifest, &customFile);

// Save manifest
// Save copy first and then copy it to the main manifest, matching backup completion semantics.
IoWrite *const manifestWrite = storageWriteIo(
storageNewWriteP(
storageRepoWrite(),
manifestFileName
manifestFileNameCopy
));

manifestSave(manifest, manifestWrite);

storageCopy(
storageNewReadP(storage, manifestFileNameCopy),
storageNewWriteP(storageRepoWrite(), manifestFileName));
}
MEM_CONTEXT_TEMP_END();

Expand Down
87 changes: 69 additions & 18 deletions test/src/module/command/repoTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Test Repo Commands
#include "info/infoBackup.h"

#define TEST_BACKUP_LABEL_FULL "20260201-173010F"
#define TEST_BACKUP_LABEL_RESUME "20260201-173011F"
#define TEST_STANZA "testStanza01"

#define TEST_DATA \
Expand Down Expand Up @@ -132,6 +133,23 @@ testManifestCustomFilesValidate(Manifest *manifest)
FUNCTION_HARNESS_RETURN(STRING, result);
}

static bool
testBackupManifestCopyValidate(const Storage *const storage, const String *const backupLabel)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STORAGE, storage);
FUNCTION_HARNESS_PARAM(STRING, backupLabel);
FUNCTION_HARNESS_END();

const String *const manifestFile = strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strZ(backupLabel));

const bool result = bufEq(
storageGetP(storageNewReadP(storage, manifestFile)),
storageGetP(storageNewReadP(storage, strNewFmt("%s" INFO_COPY_EXT, strZ(manifestFile)))));

FUNCTION_HARNESS_RETURN(BOOL, result);
}

/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
Expand Down Expand Up @@ -1518,7 +1536,11 @@ testRun(void)

TEST_RESULT_VOID(cmdStoragePush(), "push file");
TEST_RESULT_LOG("P00 INFO: push file path/aaa.txt to the archive.");
TEST_STORAGE_LIST(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL, "aaa.txt\nbackup.manifest\n", .comment = "check path exists and file added");
TEST_STORAGE_LIST(
storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL,
"aaa.txt\nbackup.manifest\nbackup.manifest.copy\n", .comment = "check path exists and file added");
TEST_RESULT_BOOL(
testBackupManifestCopyValidate(storageRepo(), STRDEF(TEST_BACKUP_LABEL_FULL)), true, "check manifest copy");

TEST_STORAGE_GET(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL "/aaa.txt", "TESTDATA");

Expand All @@ -1538,7 +1560,11 @@ testRun(void)

TEST_RESULT_VOID(cmdStoragePush(), "push file");
TEST_RESULT_LOG("P00 INFO: push file path/aaa.txt to the archive.");
TEST_STORAGE_LIST(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL, "aaa.txt\nbackup.manifest\n", .comment = "check path exists and file added");
TEST_STORAGE_LIST(
storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL,
"aaa.txt\nbackup.manifest\nbackup.manifest.copy\n", .comment = "check path exists and file added");
TEST_RESULT_BOOL(
testBackupManifestCopyValidate(storageRepo(), STRDEF(TEST_BACKUP_LABEL_FULL)), true, "check manifest copy");

TEST_STORAGE_GET(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL "/aaa.txt", TEST_DATA);

Expand All @@ -1562,15 +1588,37 @@ testRun(void)
hrnCfgArgRawZ(argList, cfgOptCompressLevel, "3");
strLstAddZ(argList, "path/aaa.txt");

HRN_CFG_LOAD(cfgCmdRepoPush, argList);

TEST_RESULT_VOID(cmdStoragePush(), "push file");
TEST_RESULT_LOG("P00 INFO: push file path/aaa.txt to the archive.");
TEST_STORAGE_LIST(
storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL,
"aaa.txt\naaa.txt.gz\nbackup.manifest\nbackup.manifest.copy\n", .comment = "check path exists and file added");
TEST_RESULT_BOOL(
testBackupManifestCopyValidate(storageRepo(), STRDEF(TEST_BACKUP_LABEL_FULL)), true, "check manifest copy");

TEST_STORAGE_GET(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL "/aaa.txt", TEST_DATA, .compressType = compressTypeGz);

manifest = manifestLoadFile(
storageRepo(), STR(STORAGE_REPO_BACKUP "/" TEST_BACKUP_LABEL_FULL "/" BACKUP_MANIFEST_FILE), cipherTypeNone, NULL);

/* Check manifest record */
TEST_RESULT_STR_Z(
testManifestCustomFilesValidate(manifest),
"aaa.txt 445\naaa.txt.gz 445\n",
"compare file list");

TEST_TITLE("do not push to resumable backup manifest copy");
HRN_INFO_PUT(
storageRepoWrite(), STORAGE_REPO_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL "/" BACKUP_MANIFEST_FILE,
storageRepoWrite(), STORAGE_REPO_BACKUP "/" TEST_BACKUP_LABEL_RESUME "/" BACKUP_MANIFEST_FILE INFO_COPY_EXT,
TEST_MANIFEST_HEADER
"\n"
"[backup:db]\n"
"db-catalog-version=201608131\n"
"db-control-version=960\n"
"db-id=1\n"
"db-system-id=" HRN_PG_SYSTEMID_94_Z "\n" // 9.4 system id is used so version will trigger error
"db-system-id=" HRN_PG_SYSTEMID_94_Z "\n"
"db-version=\"9.6\"\n"
TEST_MANIFEST_OPTION_ALL
TEST_MANIFEST_TARGET
Expand All @@ -1581,24 +1629,27 @@ testRun(void)
TEST_MANIFEST_LINK_DEFAULT
TEST_MANIFEST_PATH
TEST_MANIFEST_PATH_DEFAULT,
.comment = "manifest db section mismatch");
.comment = "manifest copy only");

argList = strLstNew();
hrnCfgArgKeyRawZ(argList, cfgOptRepoPath, 1, TEST_PATH "/bogus");
hrnCfgArgKeyRawZ(argList, cfgOptRepoPath, 2, TEST_PATH "/repo");
hrnCfgArgRawZ(argList, cfgOptCompressType, "none");
hrnCfgArgRawZ(argList, cfgOptStanza, TEST_STANZA);
hrnCfgArgRawZ(argList, cfgOptSet, TEST_BACKUP_LABEL_RESUME);
hrnCfgArgRawZ(argList, cfgOptRepo, "2");
strLstAddZ(argList, "path/aaa.txt");

HRN_CFG_LOAD(cfgCmdRepoPush, argList);

TEST_RESULT_VOID(cmdStoragePush(), "push file");
TEST_ERROR(
cmdStoragePush(), FileMissingError,
"unable to open missing file '" TEST_PATH "/repo/backup/" TEST_STANZA "/" TEST_BACKUP_LABEL_RESUME
"/backup.manifest' for read");
TEST_RESULT_LOG("P00 INFO: push file path/aaa.txt to the archive.");
TEST_STORAGE_LIST(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL, "aaa.txt\naaa.txt.gz\nbackup.manifest\n", .comment = "check path exists and file added");

TEST_STORAGE_GET(storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_FULL "/aaa.txt", TEST_DATA, .compressType = compressTypeGz);

manifest = manifestLoadFile(
storageRepo(), STR(STORAGE_REPO_BACKUP "/" TEST_BACKUP_LABEL_FULL "/" BACKUP_MANIFEST_FILE), cipherTypeNone, NULL);

/* Check manifest record */
TEST_RESULT_STR_Z(
testManifestCustomFilesValidate(manifest),
"aaa.txt 445\naaa.txt.gz 445\n",
"compare file list");
TEST_STORAGE_LIST(
storageRepo(), STORAGE_PATH_BACKUP "/" TEST_STANZA "/" TEST_BACKUP_LABEL_RESUME,
"backup.manifest.copy\n", .comment = "main manifest was not created");

TEST_TITLE("push encrypted file not supported");
argList = strLstNew();
Expand Down
Loading