Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 7211: support concatenate objects #7452

Merged
merged 1 commit into from
Mar 4, 2024
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
1 change: 1 addition & 0 deletions changelogs/unreleased/7452-Lyndon-Li
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix issue #7211. Enable advanced feature capability and add support to concatenate objects for unified repo.
33 changes: 33 additions & 0 deletions pkg/repository/udmrepo/kopialib/lib_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,39 @@
return nil
}

func (kr *kopiaRepository) GetAdvancedFeatures() udmrepo.AdvancedFeatureInfo {
return udmrepo.AdvancedFeatureInfo{
MultiPartBackup: true,
}

Check warning on line 372 in pkg/repository/udmrepo/kopialib/lib_repo.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/udmrepo/kopialib/lib_repo.go#L369-L372

Added lines #L369 - L372 were not covered by tests
}

func (kr *kopiaRepository) ConcatenateObjects(ctx context.Context, objectIDs []udmrepo.ID) (udmrepo.ID, error) {
if kr.rawWriter == nil {
return "", errors.New("repo writer is closed or not open")
}

if len(objectIDs) == 0 {
return udmrepo.ID(""), errors.New("object list is empty")
}

rawIDs := []object.ID{}
for _, id := range objectIDs {
rawID, err := object.ParseID(string(id))
if err != nil {
return udmrepo.ID(""), errors.Wrapf(err, "error to parse object ID from %v", id)
}

rawIDs = append(rawIDs, rawID)
}

result, err := kr.rawWriter.ConcatenateObjects(ctx, rawIDs)
if err != nil {
return udmrepo.ID(""), errors.Wrap(err, "error to concatenate objects")
}

return udmrepo.ID(result.String()), nil
}

// updateProgress is called when the repository writes a piece of blob data to the storage during data write
func (kr *kopiaRepository) updateProgress(uploaded int64) {
total := atomic.AddInt64(&kr.uploaded, uploaded)
Expand Down
72 changes: 72 additions & 0 deletions pkg/repository/udmrepo/kopialib/lib_repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,78 @@ func TestFlush(t *testing.T) {
}
}

func TestConcatenateObjects(t *testing.T) {
testCases := []struct {
name string
setWriter bool
rawWriter *repomocks.DirectRepositoryWriter
rawWriterRetErr error
objectIDs []udmrepo.ID
expectedErr string
}{
{
name: "writer is nil",
expectedErr: "repo writer is closed or not open",
},
{
name: "empty object list",
setWriter: true,
expectedErr: "object list is empty",
},
{
name: "invalid object id",
objectIDs: []udmrepo.ID{
"I123456",
"fake-id",
"I678901",
},
setWriter: true,
expectedErr: "error to parse object ID from fake-id: malformed content ID: \"fake-id\": invalid content prefix",
},
{
name: "concatenate error",
rawWriter: repomocks.NewDirectRepositoryWriter(t),
rawWriterRetErr: errors.New("fake-concatenate-error"),
objectIDs: []udmrepo.ID{
"I123456",
},
setWriter: true,
expectedErr: "error to concatenate objects: fake-concatenate-error",
},
{
name: "succeed",
rawWriter: repomocks.NewDirectRepositoryWriter(t),
objectIDs: []udmrepo.ID{
"I123456",
},
setWriter: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
kr := &kopiaRepository{}

if tc.rawWriter != nil {
require.NotNil(t, tc.rawWriter)
tc.rawWriter.On("ConcatenateObjects", mock.Anything, mock.Anything).Return(object.ID{}, tc.rawWriterRetErr)
}

if tc.setWriter {
kr.rawWriter = tc.rawWriter
}

_, err := kr.ConcatenateObjects(context.Background(), tc.objectIDs)

if tc.expectedErr == "" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tc.expectedErr)
}
})
}
}

func TestNewObjectWriter(t *testing.T) {
rawObjWriter := repomocks.NewWriter(t)
testCases := []struct {
Expand Down
108 changes: 99 additions & 9 deletions pkg/repository/udmrepo/mocks/BackupRepo.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading