mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-01 12:56:04 +00:00
* Add change-id and volume-id retrieve logic for both vks and vanilla k8s environment. * Add change-id and volume-id support code in exposer. Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
259 lines
7.8 KiB
Go
259 lines
7.8 KiB
Go
/*
|
|
Copyright The Velero Contributors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package cbtservice
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/kubernetes-csi/external-snapshot-metadata/pkg/api"
|
|
"github.com/kubernetes-csi/external-snapshot-metadata/pkg/iterator"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"k8s.io/client-go/rest"
|
|
)
|
|
|
|
func TestEmitterImplSnapshotMetadataIteratorRecord(t *testing.T) {
|
|
t.Run("records block metadata as ranges", func(t *testing.T) {
|
|
var got [][]Range
|
|
emitter := &emitterImpl{
|
|
logger: logrus.New(),
|
|
recordCallBack: func(ranges []Range) error {
|
|
got = append(got, ranges)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
err := emitter.SnapshotMetadataIteratorRecord(7, iterator.IteratorMetadata{
|
|
BlockMetadata: []*api.BlockMetadata{
|
|
{ByteOffset: 10, SizeBytes: 20},
|
|
{ByteOffset: 40, SizeBytes: 50},
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, [][]Range{
|
|
{{Offset: 10, Length: 20}},
|
|
{{Offset: 40, Length: 50}},
|
|
}, got)
|
|
})
|
|
|
|
t.Run("rejects negative block metadata", func(t *testing.T) {
|
|
callbackCalled := false
|
|
emitter := &emitterImpl{
|
|
logger: logrus.New(),
|
|
recordCallBack: func(ranges []Range) error {
|
|
callbackCalled = true
|
|
return nil
|
|
},
|
|
}
|
|
|
|
err := emitter.SnapshotMetadataIteratorRecord(3, iterator.IteratorMetadata{
|
|
BlockMetadata: []*api.BlockMetadata{{ByteOffset: -1, SizeBytes: 20}},
|
|
})
|
|
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid CBT metadata")
|
|
assert.False(t, callbackCalled)
|
|
})
|
|
|
|
t.Run("returns callback error", func(t *testing.T) {
|
|
wantErr := errors.New("record failed")
|
|
emitter := &emitterImpl{
|
|
logger: logrus.New(),
|
|
recordCallBack: func(ranges []Range) error {
|
|
return wantErr
|
|
},
|
|
}
|
|
|
|
err := emitter.SnapshotMetadataIteratorRecord(5, iterator.IteratorMetadata{
|
|
BlockMetadata: []*api.BlockMetadata{{ByteOffset: 1, SizeBytes: 2}},
|
|
})
|
|
|
|
require.ErrorIs(t, err, wantErr)
|
|
})
|
|
}
|
|
|
|
func TestEmitterImplSnapshotMetadataIteratorDone(t *testing.T) {
|
|
emitter := &emitterImpl{logger: logrus.New()}
|
|
assert.NoError(t, emitter.SnapshotMetadataIteratorDone(4))
|
|
}
|
|
|
|
func TestNewServiceInitializesFields(t *testing.T) {
|
|
logger := logrus.New()
|
|
cfg := &rest.Config{Host: "https://example.com"}
|
|
|
|
svc := NewService(logger, "velero-ns", "velero-sa", cfg)
|
|
|
|
impl, ok := svc.(*ServiceImpl)
|
|
require.True(t, ok)
|
|
assert.Same(t, logger, impl.logger)
|
|
assert.Equal(t, "velero-ns", impl.vsNamespace)
|
|
assert.Equal(t, "velero-sa", impl.SAName)
|
|
assert.Same(t, cfg, impl.clientConfig)
|
|
}
|
|
|
|
func TestNewServiceForwardsSANameToArgs(t *testing.T) {
|
|
originalBuildClients := buildClients
|
|
originalGetSnapshotMetadata := getSnapshotMetadata
|
|
t.Cleanup(func() {
|
|
buildClients = originalBuildClients
|
|
getSnapshotMetadata = originalGetSnapshotMetadata
|
|
})
|
|
|
|
buildClients = func(config *rest.Config) (iterator.Clients, error) {
|
|
return iterator.Clients{}, nil
|
|
}
|
|
|
|
var capturedArgs iterator.Args
|
|
getSnapshotMetadata = func(ctx context.Context, args iterator.Args) error {
|
|
capturedArgs = args
|
|
return nil
|
|
}
|
|
|
|
svc := NewService(logrus.New(), "velero-ns", "velero-sa", &rest.Config{Host: "https://example.com"})
|
|
|
|
err := svc.GetAllocatedBlocks(t.Context(), "snap-1", func([]Range) error { return nil })
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "velero-ns", capturedArgs.Namespace)
|
|
assert.Equal(t, "velero-ns", capturedArgs.SANamespace)
|
|
assert.Equal(t, "velero-sa", capturedArgs.SAName)
|
|
}
|
|
|
|
func TestServiceImplGetAllocatedBlocks(t *testing.T) {
|
|
originalBuildClients := buildClients
|
|
originalGetSnapshotMetadata := getSnapshotMetadata
|
|
t.Cleanup(func() {
|
|
buildClients = originalBuildClients
|
|
getSnapshotMetadata = originalGetSnapshotMetadata
|
|
})
|
|
|
|
t.Run("build clients error is returned", func(t *testing.T) {
|
|
wantErr := errors.New("build clients failed")
|
|
getSnapshotCalled := false
|
|
buildClients = func(config *rest.Config) (iterator.Clients, error) {
|
|
return iterator.Clients{}, wantErr
|
|
}
|
|
getSnapshotMetadata = func(ctx context.Context, args iterator.Args) error {
|
|
getSnapshotCalled = true
|
|
return nil
|
|
}
|
|
|
|
service := &ServiceImpl{logger: logrus.New(), clientConfig: &rest.Config{Host: "https://example.com"}}
|
|
|
|
err := service.GetAllocatedBlocks(t.Context(), "snap-1", func([]Range) error { return nil })
|
|
|
|
require.ErrorIs(t, err, wantErr)
|
|
assert.False(t, getSnapshotCalled)
|
|
})
|
|
|
|
t.Run("forwards args and callback", func(t *testing.T) {
|
|
cfg := &rest.Config{Host: "https://example.com"}
|
|
fakeClients := iterator.Clients{}
|
|
var capturedArgs iterator.Args
|
|
var recorded [][]Range
|
|
buildClients = func(config *rest.Config) (iterator.Clients, error) {
|
|
assert.Same(t, cfg, config)
|
|
return fakeClients, nil
|
|
}
|
|
getSnapshotMetadata = func(ctx context.Context, args iterator.Args) error {
|
|
capturedArgs = args
|
|
return args.Emitter.SnapshotMetadataIteratorRecord(1, iterator.IteratorMetadata{
|
|
BlockMetadata: []*api.BlockMetadata{{ByteOffset: 11, SizeBytes: 22}},
|
|
})
|
|
}
|
|
|
|
service := &ServiceImpl{
|
|
logger: logrus.New(),
|
|
vsNamespace: "velero-ns",
|
|
SAName: "sa-name",
|
|
clientConfig: cfg,
|
|
}
|
|
|
|
err := service.GetAllocatedBlocks(t.Context(), "snap-1", func(ranges []Range) error {
|
|
recorded = append(recorded, ranges)
|
|
return nil
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fakeClients, capturedArgs.Clients)
|
|
assert.Equal(t, "snap-1", capturedArgs.SnapshotName)
|
|
assert.Empty(t, capturedArgs.PrevSnapshotName)
|
|
assert.Equal(t, "velero-ns", capturedArgs.Namespace)
|
|
assert.Equal(t, "velero-ns", capturedArgs.SANamespace)
|
|
assert.Equal(t, "sa-name", capturedArgs.SAName)
|
|
assert.Equal(t, iterator.DefaultTokenExpirySeconds, capturedArgs.TokenExpirySecs)
|
|
assert.Zero(t, capturedArgs.MaxResults)
|
|
assert.Equal(t, [][]Range{{{Offset: 11, Length: 22}}}, recorded)
|
|
})
|
|
}
|
|
|
|
func TestServiceImplGetChangedBlocks(t *testing.T) {
|
|
originalBuildClients := buildClients
|
|
originalGetSnapshotMetadata := getSnapshotMetadata
|
|
t.Cleanup(func() {
|
|
buildClients = originalBuildClients
|
|
getSnapshotMetadata = originalGetSnapshotMetadata
|
|
})
|
|
|
|
buildClients = func(config *rest.Config) (iterator.Clients, error) {
|
|
return iterator.Clients{}, nil
|
|
}
|
|
|
|
t.Run("sets previous snapshot name", func(t *testing.T) {
|
|
var capturedArgs iterator.Args
|
|
getSnapshotMetadata = func(ctx context.Context, args iterator.Args) error {
|
|
capturedArgs = args
|
|
return nil
|
|
}
|
|
|
|
service := &ServiceImpl{
|
|
logger: logrus.New(),
|
|
vsNamespace: "velero-ns",
|
|
SAName: "sa-name",
|
|
clientConfig: &rest.Config{Host: "https://example.com"},
|
|
}
|
|
|
|
err := service.GetChangedBlocks(t.Context(), "snap-2", "snap-1", func([]Range) error { return nil })
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "snap-2", capturedArgs.SnapshotName)
|
|
assert.Equal(t, "snap-1", capturedArgs.PrevSnapshotID)
|
|
assert.Equal(t, "velero-ns", capturedArgs.Namespace)
|
|
assert.Equal(t, iterator.DefaultTokenExpirySeconds, capturedArgs.TokenExpirySecs)
|
|
assert.Zero(t, capturedArgs.MaxResults)
|
|
})
|
|
|
|
t.Run("returns snapshot metadata error", func(t *testing.T) {
|
|
wantErr := errors.New("metadata failed")
|
|
getSnapshotMetadata = func(ctx context.Context, args iterator.Args) error {
|
|
return wantErr
|
|
}
|
|
|
|
service := &ServiceImpl{
|
|
logger: logrus.New(),
|
|
clientConfig: &rest.Config{Host: "https://example.com"},
|
|
}
|
|
|
|
err := service.GetChangedBlocks(t.Context(), "snap-2", "snap-1", func([]Range) error { return nil })
|
|
|
|
require.ErrorIs(t, err, wantErr)
|
|
})
|
|
}
|