bump up kopia v0.13.0

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
Lyndon-Li
2023-05-15 07:23:38 +08:00
parent 4db1a781fc
commit 307b82a2ec
37 changed files with 939 additions and 747 deletions
+102 -24
View File
@@ -1,18 +1,4 @@
/*
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.
*/
// Code generated by mockery v2.22.1. DO NOT EDIT.
package mocks
@@ -64,11 +50,39 @@ func (_m *RepositoryWriter) Close(ctx context.Context) error {
return r0
}
// ConcatenateObjects provides a mock function with given fields: ctx, objectIDs
func (_m *RepositoryWriter) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
ret := _m.Called(ctx, objectIDs)
var r0 object.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) (object.ID, error)); ok {
return rf(ctx, objectIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) object.ID); ok {
r0 = rf(ctx, objectIDs)
} else {
r0 = ret.Get(0).(object.ID)
}
if rf, ok := ret.Get(1).(func(context.Context, []object.ID) error); ok {
r1 = rf(ctx, objectIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ContentInfo provides a mock function with given fields: ctx, contentID
func (_m *RepositoryWriter) ContentInfo(ctx context.Context, contentID index.ID) (index.Info, error) {
ret := _m.Called(ctx, contentID)
var r0 index.Info
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
return rf(ctx, contentID)
}
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
r0 = rf(ctx, contentID)
} else {
@@ -77,7 +91,6 @@ func (_m *RepositoryWriter) ContentInfo(ctx context.Context, contentID index.ID)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
r1 = rf(ctx, contentID)
} else {
@@ -106,6 +119,10 @@ func (_m *RepositoryWriter) FindManifests(ctx context.Context, labels map[string
ret := _m.Called(ctx, labels)
var r0 []*manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
return rf(ctx, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
r0 = rf(ctx, labels)
} else {
@@ -114,7 +131,6 @@ func (_m *RepositoryWriter) FindManifests(ctx context.Context, labels map[string
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
r1 = rf(ctx, labels)
} else {
@@ -143,6 +159,10 @@ func (_m *RepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, dat
ret := _m.Called(ctx, id, data)
var r0 *manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
return rf(ctx, id, data)
}
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
r0 = rf(ctx, id, data)
} else {
@@ -151,7 +171,6 @@ func (_m *RepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, dat
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
r1 = rf(ctx, id, data)
} else {
@@ -182,6 +201,11 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
ret := _m.Called(ctx, opt)
var r0 context.Context
var r1 repo.RepositoryWriter
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
return rf(ctx, opt)
}
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
r0 = rf(ctx, opt)
} else {
@@ -190,7 +214,6 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
}
}
var r1 repo.RepositoryWriter
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
r1 = rf(ctx, opt)
} else {
@@ -199,7 +222,6 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
r2 = rf(ctx, opt)
} else {
@@ -209,11 +231,20 @@ func (_m *RepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteSession
return r0, r1, r2
}
// OnSuccessfulFlush provides a mock function with given fields: callback
func (_m *RepositoryWriter) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
_m.Called(callback)
}
// OpenObject provides a mock function with given fields: ctx, id
func (_m *RepositoryWriter) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
ret := _m.Called(ctx, id)
var r0 object.Reader
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
r0 = rf(ctx, id)
} else {
@@ -222,7 +253,6 @@ func (_m *RepositoryWriter) OpenObject(ctx context.Context, id object.ID) (objec
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -253,6 +283,10 @@ func (_m *RepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs []obj
ret := _m.Called(ctx, objectIDs, hint)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
return rf(ctx, objectIDs, hint)
}
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
r0 = rf(ctx, objectIDs, hint)
} else {
@@ -261,7 +295,6 @@ func (_m *RepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs []obj
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
r1 = rf(ctx, objectIDs, hint)
} else {
@@ -276,13 +309,16 @@ func (_m *RepositoryWriter) PutManifest(ctx context.Context, labels map[string]s
ret := _m.Called(ctx, labels, payload)
var r0 manifest.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
return rf(ctx, labels, payload)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
r0 = rf(ctx, labels, payload)
} else {
r0 = ret.Get(0).(manifest.ID)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
r1 = rf(ctx, labels, payload)
} else {
@@ -306,6 +342,30 @@ func (_m *RepositoryWriter) Refresh(ctx context.Context) error {
return r0
}
// ReplaceManifests provides a mock function with given fields: ctx, labels, payload
func (_m *RepositoryWriter) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
ret := _m.Called(ctx, labels, payload)
var r0 manifest.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
return rf(ctx, labels, payload)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
r0 = rf(ctx, labels, payload)
} else {
r0 = ret.Get(0).(manifest.ID)
}
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
r1 = rf(ctx, labels, payload)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Time provides a mock function with given fields:
func (_m *RepositoryWriter) Time() time.Time {
ret := _m.Called()
@@ -330,6 +390,10 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
ret := _m.Called(ctx, id)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
r0 = rf(ctx, id)
} else {
@@ -338,7 +402,6 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -347,3 +410,18 @@ func (_m *RepositoryWriter) VerifyObject(ctx context.Context, id object.ID) ([]i
return r0, r1
}
type mockConstructorTestingTNewRepositoryWriter interface {
mock.TestingT
Cleanup(func())
}
// NewRepositoryWriter creates a new instance of RepositoryWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewRepositoryWriter(t mockConstructorTestingTNewRepositoryWriter) *RepositoryWriter {
mock := &RepositoryWriter{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -56,5 +56,5 @@ func (c *AzureBackend) Setup(ctx context.Context, flags map[string]string) error
}
func (c *AzureBackend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
return azure.New(ctx, &c.options)
return azure.New(ctx, &c.options, false)
}
@@ -25,8 +25,8 @@ import (
"github.com/kopia/kopia/repo/blob/throttling"
"github.com/kopia/kopia/repo/content"
"github.com/kopia/kopia/repo/encryption"
"github.com/kopia/kopia/repo/format"
"github.com/kopia/kopia/repo/hashing"
"github.com/kopia/kopia/repo/object"
"github.com/kopia/kopia/repo/splitter"
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
@@ -51,12 +51,12 @@ func setupLimits(ctx context.Context, flags map[string]string) throttling.Limits
// SetupNewRepositoryOptions setups the options when creating a new Kopia repository
func SetupNewRepositoryOptions(ctx context.Context, flags map[string]string) repo.NewRepositoryOptions {
return repo.NewRepositoryOptions{
BlockFormat: content.FormattingOptions{
BlockFormat: format.ContentFormat{
Hash: optionalHaveStringWithDefault(udmrepo.StoreOptionGenHashAlgo, flags, hashing.DefaultAlgorithm),
Encryption: optionalHaveStringWithDefault(udmrepo.StoreOptionGenEncryptAlgo, flags, encryption.DefaultAlgorithm),
},
ObjectFormat: object.Format{
ObjectFormat: format.ObjectFormat{
Splitter: optionalHaveStringWithDefault(udmrepo.StoreOptionGenSplitAlgo, flags, splitter.DefaultAlgorithm),
},
@@ -50,5 +50,5 @@ func (c *GCSBackend) Setup(ctx context.Context, flags map[string]string) error {
}
func (c *GCSBackend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
return gcs.New(ctx, &c.options)
return gcs.New(ctx, &c.options, false)
}
@@ -1,4 +1,4 @@
// Code generated by mockery v2.14.0. DO NOT EDIT.
// Code generated by mockery v2.22.1. DO NOT EDIT.
package mocks
@@ -8,8 +8,12 @@ import (
context "context"
format "github.com/kopia/kopia/repo/format"
index "github.com/kopia/kopia/repo/content/index"
indexblob "github.com/kopia/kopia/repo/content/indexblob"
manifest "github.com/kopia/kopia/repo/manifest"
mock "github.com/stretchr/testify/mock"
@@ -44,20 +48,6 @@ func (_m *DirectRepository) AlsoLogToContentLog(ctx context.Context) context.Con
return r0
}
// BlobCfg provides a mock function with given fields:
func (_m *DirectRepository) BlobCfg() content.BlobCfgBlob {
ret := _m.Called()
var r0 content.BlobCfgBlob
if rf, ok := ret.Get(0).(func() content.BlobCfgBlob); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(content.BlobCfgBlob)
}
return r0
}
// BlobReader provides a mock function with given fields:
func (_m *DirectRepository) BlobReader() blob.Reader {
ret := _m.Called()
@@ -137,6 +127,10 @@ func (_m *DirectRepository) ContentInfo(ctx context.Context, contentID index.ID)
ret := _m.Called(ctx, contentID)
var r0 index.Info
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
return rf(ctx, contentID)
}
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
r0 = rf(ctx, contentID)
} else {
@@ -145,7 +139,6 @@ func (_m *DirectRepository) ContentInfo(ctx context.Context, contentID index.ID)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
r1 = rf(ctx, contentID)
} else {
@@ -171,22 +164,6 @@ func (_m *DirectRepository) ContentReader() content.Reader {
return r0
}
// Crypter provides a mock function with given fields:
func (_m *DirectRepository) Crypter() *content.Crypter {
ret := _m.Called()
var r0 *content.Crypter
if rf, ok := ret.Get(0).(func() *content.Crypter); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*content.Crypter)
}
}
return r0
}
// DeriveKey provides a mock function with given fields: purpose, keyLength
func (_m *DirectRepository) DeriveKey(purpose []byte, keyLength int) []byte {
ret := _m.Called(purpose, keyLength)
@@ -213,6 +190,10 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
ret := _m.Called(ctx, labels)
var r0 []*manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
return rf(ctx, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
r0 = rf(ctx, labels)
} else {
@@ -221,7 +202,6 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
r1 = rf(ctx, labels)
} else {
@@ -231,11 +211,31 @@ func (_m *DirectRepository) FindManifests(ctx context.Context, labels map[string
return r0, r1
}
// FormatManager provides a mock function with given fields:
func (_m *DirectRepository) FormatManager() *format.Manager {
ret := _m.Called()
var r0 *format.Manager
if rf, ok := ret.Get(0).(func() *format.Manager); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*format.Manager)
}
}
return r0
}
// GetManifest provides a mock function with given fields: ctx, id, data
func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, data interface{}) (*manifest.EntryMetadata, error) {
ret := _m.Called(ctx, id, data)
var r0 *manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
return rf(ctx, id, data)
}
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
r0 = rf(ctx, id, data)
} else {
@@ -244,7 +244,6 @@ func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, dat
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
r1 = rf(ctx, id, data)
} else {
@@ -255,19 +254,22 @@ func (_m *DirectRepository) GetManifest(ctx context.Context, id manifest.ID, dat
}
// IndexBlobs provides a mock function with given fields: ctx, includeInactive
func (_m *DirectRepository) IndexBlobs(ctx context.Context, includeInactive bool) ([]content.IndexBlobInfo, error) {
func (_m *DirectRepository) IndexBlobs(ctx context.Context, includeInactive bool) ([]indexblob.Metadata, error) {
ret := _m.Called(ctx, includeInactive)
var r0 []content.IndexBlobInfo
if rf, ok := ret.Get(0).(func(context.Context, bool) []content.IndexBlobInfo); ok {
var r0 []indexblob.Metadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, bool) ([]indexblob.Metadata, error)); ok {
return rf(ctx, includeInactive)
}
if rf, ok := ret.Get(0).(func(context.Context, bool) []indexblob.Metadata); ok {
r0 = rf(ctx, includeInactive)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]content.IndexBlobInfo)
r0 = ret.Get(0).([]indexblob.Metadata)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok {
r1 = rf(ctx, includeInactive)
} else {
@@ -282,6 +284,11 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
ret := _m.Called(ctx, opt)
var r0 context.Context
var r1 repo.DirectRepositoryWriter
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.DirectRepositoryWriter, error)); ok {
return rf(ctx, opt)
}
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
r0 = rf(ctx, opt)
} else {
@@ -290,7 +297,6 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
}
}
var r1 repo.DirectRepositoryWriter
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.DirectRepositoryWriter); ok {
r1 = rf(ctx, opt)
} else {
@@ -299,7 +305,6 @@ func (_m *DirectRepository) NewDirectWriter(ctx context.Context, opt repo.WriteS
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
r2 = rf(ctx, opt)
} else {
@@ -314,6 +319,11 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
ret := _m.Called(ctx, opt)
var r0 context.Context
var r1 repo.RepositoryWriter
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
return rf(ctx, opt)
}
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
r0 = rf(ctx, opt)
} else {
@@ -322,7 +332,6 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
}
}
var r1 repo.RepositoryWriter
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
r1 = rf(ctx, opt)
} else {
@@ -331,7 +340,6 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
r2 = rf(ctx, opt)
} else {
@@ -342,14 +350,14 @@ func (_m *DirectRepository) NewWriter(ctx context.Context, opt repo.WriteSession
}
// ObjectFormat provides a mock function with given fields:
func (_m *DirectRepository) ObjectFormat() object.Format {
func (_m *DirectRepository) ObjectFormat() format.ObjectFormat {
ret := _m.Called()
var r0 object.Format
if rf, ok := ret.Get(0).(func() object.Format); ok {
var r0 format.ObjectFormat
if rf, ok := ret.Get(0).(func() format.ObjectFormat); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(object.Format)
r0 = ret.Get(0).(format.ObjectFormat)
}
return r0
@@ -360,6 +368,10 @@ func (_m *DirectRepository) OpenObject(ctx context.Context, id object.ID) (objec
ret := _m.Called(ctx, id)
var r0 object.Reader
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
r0 = rf(ctx, id)
} else {
@@ -368,7 +380,6 @@ func (_m *DirectRepository) OpenObject(ctx context.Context, id object.ID) (objec
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -399,6 +410,10 @@ func (_m *DirectRepository) PrefetchObjects(ctx context.Context, objectIDs []obj
ret := _m.Called(ctx, objectIDs, hint)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
return rf(ctx, objectIDs, hint)
}
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
r0 = rf(ctx, objectIDs, hint)
} else {
@@ -407,7 +422,6 @@ func (_m *DirectRepository) PrefetchObjects(ctx context.Context, objectIDs []obj
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
r1 = rf(ctx, objectIDs, hint)
} else {
@@ -466,13 +480,16 @@ func (_m *DirectRepository) Token(password string) (string, error) {
ret := _m.Called(password)
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(password)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(password)
} else {
r0 = ret.Get(0).(string)
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(password)
} else {
@@ -508,6 +525,10 @@ func (_m *DirectRepository) VerifyObject(ctx context.Context, id object.ID) ([]i
ret := _m.Called(ctx, id)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
r0 = rf(ctx, id)
} else {
@@ -516,7 +537,6 @@ func (_m *DirectRepository) VerifyObject(ctx context.Context, id object.ID) ([]i
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -1,4 +1,4 @@
// Code generated by mockery v2.14.0. DO NOT EDIT.
// Code generated by mockery v2.22.1. DO NOT EDIT.
package mocks
@@ -8,8 +8,12 @@ import (
context "context"
format "github.com/kopia/kopia/repo/format"
index "github.com/kopia/kopia/repo/content/index"
indexblob "github.com/kopia/kopia/repo/content/indexblob"
manifest "github.com/kopia/kopia/repo/manifest"
mock "github.com/stretchr/testify/mock"
@@ -44,20 +48,6 @@ func (_m *DirectRepositoryWriter) AlsoLogToContentLog(ctx context.Context) conte
return r0
}
// BlobCfg provides a mock function with given fields:
func (_m *DirectRepositoryWriter) BlobCfg() content.BlobCfgBlob {
ret := _m.Called()
var r0 content.BlobCfgBlob
if rf, ok := ret.Get(0).(func() content.BlobCfgBlob); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(content.BlobCfgBlob)
}
return r0
}
// BlobReader provides a mock function with given fields:
func (_m *DirectRepositoryWriter) BlobReader() blob.Reader {
ret := _m.Called()
@@ -106,20 +96,6 @@ func (_m *DirectRepositoryWriter) BlobVolume() blob.Volume {
return r0
}
// ChangePassword provides a mock function with given fields: ctx, newPassword
func (_m *DirectRepositoryWriter) ChangePassword(ctx context.Context, newPassword string) error {
ret := _m.Called(ctx, newPassword)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
r0 = rf(ctx, newPassword)
} else {
r0 = ret.Error(0)
}
return r0
}
// ClientOptions provides a mock function with given fields:
func (_m *DirectRepositoryWriter) ClientOptions() repo.ClientOptions {
ret := _m.Called()
@@ -148,18 +124,28 @@ func (_m *DirectRepositoryWriter) Close(ctx context.Context) error {
return r0
}
// CommitUpgrade provides a mock function with given fields: ctx
func (_m *DirectRepositoryWriter) CommitUpgrade(ctx context.Context) error {
ret := _m.Called(ctx)
// ConcatenateObjects provides a mock function with given fields: ctx, objectIDs
func (_m *DirectRepositoryWriter) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
ret := _m.Called(ctx, objectIDs)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context) error); ok {
r0 = rf(ctx)
var r0 object.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) (object.ID, error)); ok {
return rf(ctx, objectIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []object.ID) object.ID); ok {
r0 = rf(ctx, objectIDs)
} else {
r0 = ret.Error(0)
r0 = ret.Get(0).(object.ID)
}
return r0
if rf, ok := ret.Get(1).(func(context.Context, []object.ID) error); ok {
r1 = rf(ctx, objectIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ConfigFilename provides a mock function with given fields:
@@ -181,6 +167,10 @@ func (_m *DirectRepositoryWriter) ContentInfo(ctx context.Context, contentID ind
ret := _m.Called(ctx, contentID)
var r0 index.Info
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, index.ID) (index.Info, error)); ok {
return rf(ctx, contentID)
}
if rf, ok := ret.Get(0).(func(context.Context, index.ID) index.Info); ok {
r0 = rf(ctx, contentID)
} else {
@@ -189,7 +179,6 @@ func (_m *DirectRepositoryWriter) ContentInfo(ctx context.Context, contentID ind
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, index.ID) error); ok {
r1 = rf(ctx, contentID)
} else {
@@ -231,22 +220,6 @@ func (_m *DirectRepositoryWriter) ContentReader() content.Reader {
return r0
}
// Crypter provides a mock function with given fields:
func (_m *DirectRepositoryWriter) Crypter() *content.Crypter {
ret := _m.Called()
var r0 *content.Crypter
if rf, ok := ret.Get(0).(func() *content.Crypter); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*content.Crypter)
}
}
return r0
}
// DeleteManifest provides a mock function with given fields: ctx, id
func (_m *DirectRepositoryWriter) DeleteManifest(ctx context.Context, id manifest.ID) error {
ret := _m.Called(ctx, id)
@@ -287,6 +260,10 @@ func (_m *DirectRepositoryWriter) FindManifests(ctx context.Context, labels map[
ret := _m.Called(ctx, labels)
var r0 []*manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*manifest.EntryMetadata, error)); ok {
return rf(ctx, labels)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*manifest.EntryMetadata); ok {
r0 = rf(ctx, labels)
} else {
@@ -295,7 +272,6 @@ func (_m *DirectRepositoryWriter) FindManifests(ctx context.Context, labels map[
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string) error); ok {
r1 = rf(ctx, labels)
} else {
@@ -319,11 +295,31 @@ func (_m *DirectRepositoryWriter) Flush(ctx context.Context) error {
return r0
}
// FormatManager provides a mock function with given fields:
func (_m *DirectRepositoryWriter) FormatManager() *format.Manager {
ret := _m.Called()
var r0 *format.Manager
if rf, ok := ret.Get(0).(func() *format.Manager); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*format.Manager)
}
}
return r0
}
// GetManifest provides a mock function with given fields: ctx, id, data
func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.ID, data interface{}) (*manifest.EntryMetadata, error) {
ret := _m.Called(ctx, id, data)
var r0 *manifest.EntryMetadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) (*manifest.EntryMetadata, error)); ok {
return rf(ctx, id, data)
}
if rf, ok := ret.Get(0).(func(context.Context, manifest.ID, interface{}) *manifest.EntryMetadata); ok {
r0 = rf(ctx, id, data)
} else {
@@ -332,7 +328,6 @@ func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.I
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, manifest.ID, interface{}) error); ok {
r1 = rf(ctx, id, data)
} else {
@@ -343,19 +338,22 @@ func (_m *DirectRepositoryWriter) GetManifest(ctx context.Context, id manifest.I
}
// IndexBlobs provides a mock function with given fields: ctx, includeInactive
func (_m *DirectRepositoryWriter) IndexBlobs(ctx context.Context, includeInactive bool) ([]content.IndexBlobInfo, error) {
func (_m *DirectRepositoryWriter) IndexBlobs(ctx context.Context, includeInactive bool) ([]indexblob.Metadata, error) {
ret := _m.Called(ctx, includeInactive)
var r0 []content.IndexBlobInfo
if rf, ok := ret.Get(0).(func(context.Context, bool) []content.IndexBlobInfo); ok {
var r0 []indexblob.Metadata
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, bool) ([]indexblob.Metadata, error)); ok {
return rf(ctx, includeInactive)
}
if rf, ok := ret.Get(0).(func(context.Context, bool) []indexblob.Metadata); ok {
r0 = rf(ctx, includeInactive)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]content.IndexBlobInfo)
r0 = ret.Get(0).([]indexblob.Metadata)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok {
r1 = rf(ctx, includeInactive)
} else {
@@ -370,6 +368,11 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
ret := _m.Called(ctx, opt)
var r0 context.Context
var r1 repo.DirectRepositoryWriter
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.DirectRepositoryWriter, error)); ok {
return rf(ctx, opt)
}
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
r0 = rf(ctx, opt)
} else {
@@ -378,7 +381,6 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
}
}
var r1 repo.DirectRepositoryWriter
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.DirectRepositoryWriter); ok {
r1 = rf(ctx, opt)
} else {
@@ -387,7 +389,6 @@ func (_m *DirectRepositoryWriter) NewDirectWriter(ctx context.Context, opt repo.
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
r2 = rf(ctx, opt)
} else {
@@ -418,6 +419,11 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
ret := _m.Called(ctx, opt)
var r0 context.Context
var r1 repo.RepositoryWriter
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error)); ok {
return rf(ctx, opt)
}
if rf, ok := ret.Get(0).(func(context.Context, repo.WriteSessionOptions) context.Context); ok {
r0 = rf(ctx, opt)
} else {
@@ -426,7 +432,6 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
}
}
var r1 repo.RepositoryWriter
if rf, ok := ret.Get(1).(func(context.Context, repo.WriteSessionOptions) repo.RepositoryWriter); ok {
r1 = rf(ctx, opt)
} else {
@@ -435,7 +440,6 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, repo.WriteSessionOptions) error); ok {
r2 = rf(ctx, opt)
} else {
@@ -446,24 +450,33 @@ func (_m *DirectRepositoryWriter) NewWriter(ctx context.Context, opt repo.WriteS
}
// ObjectFormat provides a mock function with given fields:
func (_m *DirectRepositoryWriter) ObjectFormat() object.Format {
func (_m *DirectRepositoryWriter) ObjectFormat() format.ObjectFormat {
ret := _m.Called()
var r0 object.Format
if rf, ok := ret.Get(0).(func() object.Format); ok {
var r0 format.ObjectFormat
if rf, ok := ret.Get(0).(func() format.ObjectFormat); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(object.Format)
r0 = ret.Get(0).(format.ObjectFormat)
}
return r0
}
// OnSuccessfulFlush provides a mock function with given fields: callback
func (_m *DirectRepositoryWriter) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
_m.Called(callback)
}
// OpenObject provides a mock function with given fields: ctx, id
func (_m *DirectRepositoryWriter) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
ret := _m.Called(ctx, id)
var r0 object.Reader
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) (object.Reader, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) object.Reader); ok {
r0 = rf(ctx, id)
} else {
@@ -472,7 +485,6 @@ func (_m *DirectRepositoryWriter) OpenObject(ctx context.Context, id object.ID)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -503,6 +515,10 @@ func (_m *DirectRepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs
ret := _m.Called(ctx, objectIDs, hint)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) ([]index.ID, error)); ok {
return rf(ctx, objectIDs, hint)
}
if rf, ok := ret.Get(0).(func(context.Context, []object.ID, string) []index.ID); ok {
r0 = rf(ctx, objectIDs, hint)
} else {
@@ -511,7 +527,6 @@ func (_m *DirectRepositoryWriter) PrefetchObjects(ctx context.Context, objectIDs
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, []object.ID, string) error); ok {
r1 = rf(ctx, objectIDs, hint)
} else {
@@ -526,13 +541,16 @@ func (_m *DirectRepositoryWriter) PutManifest(ctx context.Context, labels map[st
ret := _m.Called(ctx, labels, payload)
var r0 manifest.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
return rf(ctx, labels, payload)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
r0 = rf(ctx, labels, payload)
} else {
r0 = ret.Get(0).(manifest.ID)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
r1 = rf(ctx, labels, payload)
} else {
@@ -556,50 +574,23 @@ func (_m *DirectRepositoryWriter) Refresh(ctx context.Context) error {
return r0
}
// RollbackUpgrade provides a mock function with given fields: ctx
func (_m *DirectRepositoryWriter) RollbackUpgrade(ctx context.Context) error {
ret := _m.Called(ctx)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context) error); ok {
r0 = rf(ctx)
} else {
r0 = ret.Error(0)
}
return r0
}
// SetParameters provides a mock function with given fields: ctx, m, blobcfg
func (_m *DirectRepositoryWriter) SetParameters(ctx context.Context, m content.MutableParameters, blobcfg content.BlobCfgBlob) error {
ret := _m.Called(ctx, m, blobcfg)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, content.MutableParameters, content.BlobCfgBlob) error); ok {
r0 = rf(ctx, m, blobcfg)
} else {
r0 = ret.Error(0)
}
return r0
}
// SetUpgradeLockIntent provides a mock function with given fields: ctx, l
func (_m *DirectRepositoryWriter) SetUpgradeLockIntent(ctx context.Context, l content.UpgradeLock) (*content.UpgradeLock, error) {
ret := _m.Called(ctx, l)
var r0 *content.UpgradeLock
if rf, ok := ret.Get(0).(func(context.Context, content.UpgradeLock) *content.UpgradeLock); ok {
r0 = rf(ctx, l)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*content.UpgradeLock)
}
}
// ReplaceManifests provides a mock function with given fields: ctx, labels, payload
func (_m *DirectRepositoryWriter) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
ret := _m.Called(ctx, labels, payload)
var r0 manifest.ID
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, content.UpgradeLock) error); ok {
r1 = rf(ctx, l)
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) (manifest.ID, error)); ok {
return rf(ctx, labels, payload)
}
if rf, ok := ret.Get(0).(func(context.Context, map[string]string, interface{}) manifest.ID); ok {
r0 = rf(ctx, labels, payload)
} else {
r0 = ret.Get(0).(manifest.ID)
}
if rf, ok := ret.Get(1).(func(context.Context, map[string]string, interface{}) error); ok {
r1 = rf(ctx, labels, payload)
} else {
r1 = ret.Error(1)
}
@@ -642,13 +633,16 @@ func (_m *DirectRepositoryWriter) Token(password string) (string, error) {
ret := _m.Called(password)
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(password)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(password)
} else {
r0 = ret.Get(0).(string)
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(password)
} else {
@@ -684,6 +678,10 @@ func (_m *DirectRepositoryWriter) VerifyObject(ctx context.Context, id object.ID
ret := _m.Called(ctx, id)
var r0 []index.ID
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, object.ID) ([]index.ID, error)); ok {
return rf(ctx, id)
}
if rf, ok := ret.Get(0).(func(context.Context, object.ID) []index.ID); ok {
r0 = rf(ctx, id)
} else {
@@ -692,7 +690,6 @@ func (_m *DirectRepositoryWriter) VerifyObject(ctx context.Context, id object.ID
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, object.ID) error); ok {
r1 = rf(ctx, id)
} else {
@@ -1,62 +1,99 @@
// Code generated by mockery v2.14.0. DO NOT EDIT.
// Code generated by mockery v2.22.1. DO NOT EDIT.
package mocks
import mock "github.com/stretchr/testify/mock"
import (
mock "github.com/stretchr/testify/mock"
zapcore "go.uber.org/zap/zapcore"
)
// Logger is an autogenerated mock type for the Logger type
type Logger struct {
// Core is an autogenerated mock type for the Core type
type Core struct {
mock.Mock
}
// Debugf provides a mock function with given fields: msg, args
func (_m *Logger) Debugf(msg string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, msg)
_ca = append(_ca, args...)
_m.Called(_ca...)
// Check provides a mock function with given fields: _a0, _a1
func (_m *Core) Check(_a0 zapcore.Entry, _a1 *zapcore.CheckedEntry) *zapcore.CheckedEntry {
ret := _m.Called(_a0, _a1)
var r0 *zapcore.CheckedEntry
if rf, ok := ret.Get(0).(func(zapcore.Entry, *zapcore.CheckedEntry) *zapcore.CheckedEntry); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*zapcore.CheckedEntry)
}
}
return r0
}
// Debugw provides a mock function with given fields: msg, keyValuePairs
func (_m *Logger) Debugw(msg string, keyValuePairs ...interface{}) {
var _ca []interface{}
_ca = append(_ca, msg)
_ca = append(_ca, keyValuePairs...)
_m.Called(_ca...)
// Enabled provides a mock function with given fields: _a0
func (_m *Core) Enabled(_a0 zapcore.Level) bool {
ret := _m.Called(_a0)
var r0 bool
if rf, ok := ret.Get(0).(func(zapcore.Level) bool); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// Errorf provides a mock function with given fields: msg, args
func (_m *Logger) Errorf(msg string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, msg)
_ca = append(_ca, args...)
_m.Called(_ca...)
// Sync provides a mock function with given fields:
func (_m *Core) Sync() error {
ret := _m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// Infof provides a mock function with given fields: msg, args
func (_m *Logger) Infof(msg string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, msg)
_ca = append(_ca, args...)
_m.Called(_ca...)
// With provides a mock function with given fields: _a0
func (_m *Core) With(_a0 []zapcore.Field) zapcore.Core {
ret := _m.Called(_a0)
var r0 zapcore.Core
if rf, ok := ret.Get(0).(func([]zapcore.Field) zapcore.Core); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(zapcore.Core)
}
}
return r0
}
// Warnf provides a mock function with given fields: msg, args
func (_m *Logger) Warnf(msg string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, msg)
_ca = append(_ca, args...)
_m.Called(_ca...)
// Write provides a mock function with given fields: _a0, _a1
func (_m *Core) Write(_a0 zapcore.Entry, _a1 []zapcore.Field) error {
ret := _m.Called(_a0, _a1)
var r0 error
if rf, ok := ret.Get(0).(func(zapcore.Entry, []zapcore.Field) error); ok {
r0 = rf(_a0, _a1)
} else {
r0 = ret.Error(0)
}
return r0
}
type mockConstructorTestingTNewLogger interface {
type mockConstructorTestingTNewCore interface {
mock.TestingT
Cleanup(func())
}
// NewLogger creates a new instance of Logger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewLogger(t mockConstructorTestingTNewLogger) *Logger {
mock := &Logger{}
// NewCore creates a new instance of Core. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewCore(t mockConstructorTestingTNewCore) *Core {
mock := &Core{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
@@ -59,5 +59,5 @@ func (c *S3Backend) Setup(ctx context.Context, flags map[string]string) error {
}
func (c *S3Backend) Connect(ctx context.Context, isCreate bool) (blob.Storage, error) {
return s3.New(ctx, &c.options)
return s3.New(ctx, &c.options, false)
}
@@ -18,12 +18,13 @@ package backend
import (
"context"
"fmt"
"testing"
"github.com/kopia/kopia/repo/logging"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
storagemocks "github.com/vmware-tanzu/velero/pkg/repository/udmrepo/kopialib/backend/mocks"
)
@@ -31,13 +32,13 @@ import (
func TestOptionalHaveBool(t *testing.T) {
var expectMsg string
testCases := []struct {
name string
key string
flags map[string]string
logger *storagemocks.Logger
retFuncErrorf func(mock.Arguments)
expectMsg string
retValue bool
name string
key string
flags map[string]string
logger *storagemocks.Core
retFuncCheck func(mock.Arguments)
expectMsg string
retValue bool
}{
{
name: "key not exist",
@@ -59,9 +60,12 @@ func TestOptionalHaveBool(t *testing.T) {
flags: map[string]string{
"fake-key": "fake-value",
},
logger: new(storagemocks.Logger),
retFuncErrorf: func(args mock.Arguments) {
expectMsg = fmt.Sprintf(args[0].(string), args[1].(string), args[2].(string), args[3].(error))
logger: new(storagemocks.Core),
retFuncCheck: func(args mock.Arguments) {
ent := args[0].(zapcore.Entry)
if ent.Level == zapcore.ErrorLevel {
expectMsg = ent.Message
}
},
expectMsg: "Ignore fake-key, value [fake-value] is invalid, err strconv.ParseBool: parsing \"fake-value\": invalid syntax",
retValue: false,
@@ -71,11 +75,12 @@ func TestOptionalHaveBool(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.logger != nil {
tc.logger.On("Errorf", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(tc.retFuncErrorf)
tc.logger.On("Enabled", mock.Anything).Return(true)
tc.logger.On("Check", mock.Anything, mock.Anything).Run(tc.retFuncCheck).Return(&zapcore.CheckedEntry{})
}
ctx := logging.WithLogger(context.Background(), func(module string) logging.Logger {
return tc.logger
return zap.New(tc.logger).Sugar()
})
retValue := optionalHaveBool(ctx, tc.key, tc.flags)
+10 -11
View File
@@ -19,7 +19,6 @@ package kopialib
import (
"context"
"os"
"runtime"
"strings"
"sync/atomic"
"time"
@@ -234,7 +233,12 @@ func (kr *kopiaRepository) OpenObject(ctx context.Context, id udmrepo.ID) (udmre
return nil, errors.New("repo is closed or not open")
}
reader, err := kr.rawRepo.OpenObject(logging.SetupKopiaLog(ctx, kr.logger), object.ID(id))
objID, err := object.ParseID(string(id))
if err != nil {
return nil, errors.Wrapf(err, "error to parse object ID from %v", id)
}
reader, err := kr.rawRepo.OpenObject(logging.SetupKopiaLog(ctx, kr.logger), objID)
if err != nil {
return nil, errors.Wrap(err, "error to open object")
}
@@ -309,8 +313,8 @@ func (kr *kopiaRepository) NewObjectWriter(ctx context.Context, opt udmrepo.Obje
writer := kr.rawWriter.NewObjectWriter(logging.SetupKopiaLog(ctx, kr.logger), object.WriterOptions{
Description: opt.Description,
Prefix: index.ID(opt.Prefix),
AsyncWrites: getAsyncWrites(),
Prefix: index.IDPrefix(opt.Prefix),
AsyncWrites: opt.AsyncWrites,
Compressor: getCompressorForObject(opt),
})
@@ -438,7 +442,7 @@ func (kow *kopiaObjectWriter) Checkpoint() (udmrepo.ID, error) {
return udmrepo.ID(""), errors.Wrap(err, "error to checkpoint object")
}
return udmrepo.ID(id), nil
return udmrepo.ID(id.String()), nil
}
func (kow *kopiaObjectWriter) Result() (udmrepo.ID, error) {
@@ -451,7 +455,7 @@ func (kow *kopiaObjectWriter) Result() (udmrepo.ID, error) {
return udmrepo.ID(""), errors.Wrap(err, "error to wait object")
}
return udmrepo.ID(id), nil
return udmrepo.ID(id.String()), nil
}
func (kow *kopiaObjectWriter) Close() error {
@@ -469,11 +473,6 @@ func (kow *kopiaObjectWriter) Close() error {
return nil
}
// getAsyncWrites returns the number of concurrent async writes
func getAsyncWrites() int {
return runtime.NumCPU()
}
// getCompressorForObject returns the compressor for an object, at present, we don't support compression
func getCompressorForObject(opt udmrepo.ObjectWriteOptions) compression.Name {
return ""
@@ -23,6 +23,7 @@ import (
"time"
"github.com/kopia/kopia/repo"
"github.com/kopia/kopia/repo/manifest"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -262,14 +263,14 @@ func TestMaintain(t *testing.T) {
func TestWriteInitParameters(t *testing.T) {
var directRpo *repomocks.DirectRepository
testCases := []struct {
name string
repoOptions udmrepo.RepoOptions
returnRepo *repomocks.DirectRepository
returnRepoWriter *repomocks.DirectRepositoryWriter
repoOpen func(context.Context, string, string, *repo.Options) (repo.Repository, error)
newRepoWriterError error
findManifestError error
expectedErr string
name string
repoOptions udmrepo.RepoOptions
returnRepo *repomocks.DirectRepository
returnRepoWriter *repomocks.DirectRepositoryWriter
repoOpen func(context.Context, string, string, *repo.Options) (repo.Repository, error)
newRepoWriterError error
replaceManifestError error
expectedErr string
}{
{
name: "repo open fail, repo not exist",
@@ -315,10 +316,10 @@ func TestWriteInitParameters(t *testing.T) {
repoOpen: func(context.Context, string, string, *repo.Options) (repo.Repository, error) {
return directRpo, nil
},
returnRepo: new(repomocks.DirectRepository),
returnRepoWriter: new(repomocks.DirectRepositoryWriter),
findManifestError: errors.New("fake-find-manifest-error"),
expectedErr: "error to init write repo parameters: error to set maintenance params: error looking for maintenance manifest: fake-find-manifest-error",
returnRepo: new(repomocks.DirectRepository),
returnRepoWriter: new(repomocks.DirectRepositoryWriter),
replaceManifestError: errors.New("fake-replace-manifest-error"),
expectedErr: "error to init write repo parameters: error to set maintenance params: put manifest: fake-replace-manifest-error",
},
}
@@ -343,7 +344,7 @@ func TestWriteInitParameters(t *testing.T) {
if tc.returnRepoWriter != nil {
tc.returnRepoWriter.On("Close", mock.Anything).Return(nil)
tc.returnRepoWriter.On("FindManifests", mock.Anything, mock.Anything).Return(nil, tc.findManifestError)
tc.returnRepoWriter.On("ReplaceManifests", mock.Anything, mock.Anything, mock.Anything).Return(manifest.ID(""), tc.replaceManifestError)
}
err := writeInitParameters(ctx, tc.repoOptions, logger)
+1
View File
@@ -68,6 +68,7 @@ type ObjectWriteOptions struct {
Prefix ID // A prefix of the name used to save the object
AccessMode int // OBJECT_DATA_ACCESS_*
BackupMode int // OBJECT_DATA_BACKUP_*
AsyncWrites int // Num of async writes for the object, 0 means no async write
}
// BackupRepoService is used to initialize, open or maintain a backup repository
+7
View File
@@ -27,3 +27,10 @@ func NewLogger() logrus.FieldLogger {
logger.Out = io.Discard
return logrus.NewEntry(logger)
}
func NewLoggerWithLevel(level logrus.Level) logrus.FieldLogger {
logger := logrus.New()
logger.Out = io.Discard
logger.Level = level
return logrus.NewEntry(logger)
}
+2
View File
@@ -151,3 +151,5 @@ func (p *Progress) ProgressBytes(processedBytes int64, totalBytes int64) {
atomic.StoreInt64(&p.estimatedTotalBytes, totalBytes)
p.UpdateProgress()
}
func (p *Progress) FinishedFile(fname string, err error) {}
+38 -8
View File
@@ -55,7 +55,7 @@ func NewShimRepo(repo udmrepo.BackupRepo) repo.RepositoryWriter {
// OpenObject open specific object
func (sr *shimRepository) OpenObject(ctx context.Context, id object.ID) (object.Reader, error) {
reader, err := sr.udmRepo.OpenObject(ctx, udmrepo.ID(id))
reader, err := sr.udmRepo.OpenObject(ctx, udmrepo.ID(id.String()))
if err != nil {
return nil, errors.Wrapf(err, "failed to open object with id %v", id)
}
@@ -70,7 +70,7 @@ func (sr *shimRepository) OpenObject(ctx context.Context, id object.ID) (object.
// VerifyObject not supported
func (sr *shimRepository) VerifyObject(ctx context.Context, id object.ID) ([]content.ID, error) {
return nil, errors.New("not supported")
return nil, errors.New("VerifyObject is not supported")
}
// Get one or more manifest data that match the specific manifest id
@@ -135,12 +135,12 @@ func (sr *shimRepository) ClientOptions() repo.ClientOptions {
// Refresh not supported
func (sr *shimRepository) Refresh(ctx context.Context) error {
return errors.New("not supported")
return errors.New("Refresh is not supported")
}
// ContentInfo not supported
func (sr *shimRepository) ContentInfo(ctx context.Context, contentID content.ID) (content.Info, error) {
return nil, errors.New("not supported")
return nil, errors.New("ContentInfo is not supported")
}
// PrefetchContents is not supported by unified repo
@@ -150,7 +150,7 @@ func (sr *shimRepository) PrefetchContents(ctx context.Context, contentIDs []con
// PrefetchObjects is not supported by unified repo
func (sr *shimRepository) PrefetchObjects(ctx context.Context, objectIDs []object.ID, hint string) ([]content.ID, error) {
return nil, errors.New("not supported")
return nil, errors.New("PrefetchObjects is not supported")
}
// UpdateDescription is not supported by unified repo
@@ -159,7 +159,7 @@ func (sr *shimRepository) UpdateDescription(d string) {
// NewWriter is not supported by unified repo
func (sr *shimRepository) NewWriter(ctx context.Context, option repo.WriteSessionOptions) (context.Context, repo.RepositoryWriter, error) {
return nil, nil, errors.New("not supported")
return nil, nil, errors.New("NewWriter is not supported")
}
// Close will close unified repo
@@ -174,6 +174,7 @@ func (sr *shimRepository) NewObjectWriter(ctx context.Context, option object.Wri
opt.Prefix = udmrepo.ID(option.Prefix)
opt.FullPath = ""
opt.AccessMode = udmrepo.ObjectDataAccessModeFile
opt.AsyncWrites = option.AsyncWrites
if strings.HasPrefix(option.Description, "DIR:") {
opt.DataType = udmrepo.ObjectDataTypeMetadata
@@ -208,11 +209,22 @@ func (sr *shimRepository) DeleteManifest(ctx context.Context, id manifest.ID) er
return sr.udmRepo.DeleteManifest(ctx, udmrepo.ID(id))
}
func (sr *shimRepository) ReplaceManifests(ctx context.Context, labels map[string]string, payload interface{}) (manifest.ID, error) {
return manifest.ID(""), errors.New("ReplaceManifests is not supported")
}
// Flush all the unifited repository data
func (sr *shimRepository) Flush(ctx context.Context) error {
return sr.udmRepo.Flush(ctx)
}
func (sr *shimRepository) ConcatenateObjects(ctx context.Context, objectIDs []object.ID) (object.ID, error) {
return object.ID{}, errors.New("ConcatenateObjects is not supported")
}
func (sr *shimRepository) OnSuccessfulFlush(callback repo.RepositoryWriterCallback) {
}
// Flush all the unifited repository data
func (sr *shimObjectReader) Read(p []byte) (n int, err error) {
return sr.repoReader.Read(p)
@@ -240,13 +252,31 @@ func (sr *shimObjectWriter) Write(p []byte) (n int, err error) {
// Periodically called to preserve the state of data written to the repo so far.
func (sr *shimObjectWriter) Checkpoint() (object.ID, error) {
id, err := sr.repoWriter.Checkpoint()
return object.ID(id), err
if err != nil {
return object.ID{}, err
}
objID, err := object.ParseID(string(id))
if err != nil {
return object.ID{}, errors.Wrapf(err, "error to parse object ID from %v", id)
}
return objID, err
}
// Result returns the object's unified identifier after the write completes.
func (sr *shimObjectWriter) Result() (object.ID, error) {
id, err := sr.repoWriter.Result()
return object.ID(id), err
if err != nil {
return object.ID{}, err
}
objID, err := object.ParseID(string(id))
if err != nil {
return object.ID{}, errors.Wrapf(err, "error to parse object ID from %v", id)
}
return objID, err
}
// Close closes the repository and releases all resources.
+19 -30
View File
@@ -44,9 +44,7 @@ import (
)
// All function mainly used to make testing more convenient
var treeForSourceFunc = policy.TreeForSource
var applyRetentionPolicyFunc = policy.ApplyRetentionPolicy
var setPolicyFunc = policy.SetPolicy
var saveSnapshotFunc = snapshot.SaveSnapshot
var loadSnapshotFunc = snapshot.LoadSnapshot
@@ -72,24 +70,17 @@ func newOptionalBool(b bool) *policy.OptionalBool {
}
// setupDefaultPolicy set default policy for kopia
func setupDefaultPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo) error {
return setPolicyFunc(ctx, rep, sourceInfo, &policy.Policy{
RetentionPolicy: policy.RetentionPolicy{
KeepLatest: newOptionalInt(math.MaxInt32),
},
CompressionPolicy: policy.CompressionPolicy{
CompressorName: "none",
},
UploadPolicy: policy.UploadPolicy{
MaxParallelFileReads: newOptionalInt(runtime.NumCPU()),
},
SchedulingPolicy: policy.SchedulingPolicy{
Manual: true,
},
ErrorHandlingPolicy: policy.ErrorHandlingPolicy{
IgnoreUnknownTypes: newOptionalBool(true),
},
})
func setupDefaultPolicy() *policy.Tree {
defaultPolicy := *policy.DefaultPolicy
defaultPolicy.RetentionPolicy.KeepLatest = newOptionalInt(math.MaxInt32)
defaultPolicy.CompressionPolicy.CompressorName = "none"
defaultPolicy.UploadPolicy.MaxParallelFileReads = newOptionalInt(runtime.NumCPU())
defaultPolicy.UploadPolicy.ParallelUploadAboveSize = nil
defaultPolicy.SchedulingPolicy.Manual = true
defaultPolicy.ErrorHandlingPolicy.IgnoreUnknownTypes = newOptionalBool(true)
return policy.BuildTree(nil, &defaultPolicy)
}
// Backup backup specific sourcePath and update progress
@@ -193,17 +184,10 @@ func SnapshotSource(
previous = pre
}
var manifest *snapshot.Manifest
if err := setupDefaultPolicy(ctx, rep, sourceInfo); err != nil {
return "", 0, errors.Wrapf(err, "unable to set policy for si %v", sourceInfo)
}
policyTree, err := treeForSourceFunc(ctx, rep, sourceInfo)
if err != nil {
return "", 0, errors.Wrapf(err, "unable to create policy getter for si %v", sourceInfo)
}
policyTree := setupDefaultPolicy()
manifest, err = u.Upload(ctx, rootDir, policyTree, sourceInfo, previous...)
manifest, err := u.Upload(ctx, rootDir, policyTree, sourceInfo, previous...)
if err != nil {
return "", 0, errors.Wrapf(err, "Failed to upload the kopia snapshot for si %v", sourceInfo)
}
@@ -247,7 +231,7 @@ func reportSnapshotStatus(manifest *snapshot.Manifest, policyTree *policy.Tree)
// findPreviousSnapshotManifest returns the list of previous snapshots for a given source, including
// last complete snapshot following it.
func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sourceInfo snapshot.SourceInfo, noLaterThan *time.Time) ([]*snapshot.Manifest, error) {
func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sourceInfo snapshot.SourceInfo, noLaterThan *fs.UTCTimestamp) ([]*snapshot.Manifest, error) {
man, err := snapshot.ListSnapshots(ctx, rep, sourceInfo)
if err != nil {
return nil, err
@@ -297,6 +281,11 @@ func Restore(ctx context.Context, rep repo.RepositoryWriter, progress *Progress,
IgnorePermissionErrors: true,
}
err = output.Init(ctx)
if err != nil {
return 0, 0, errors.Wrap(err, "error to init output")
}
stat, err := restore.Entry(kopiaCtx, rep, output, rootEntry, restore.Options{
Parallel: runtime.NumCPU(),
RestoreDirEntryAtDepth: math.MaxInt32,
-15
View File
@@ -50,8 +50,6 @@ func injectSnapshotFuncs() *snapshotMockes {
repoWriterMock: &repomocks.RepositoryWriter{},
}
setPolicyFunc = s.policyMock.SetPolicy
treeForSourceFunc = s.policyMock.TreeForSource
applyRetentionPolicyFunc = s.policyMock.ApplyRetentionPolicy
loadSnapshotFunc = s.snapshotMock.LoadSnapshot
saveSnapshotFunc = s.snapshotMock.SaveSnapshot
@@ -141,19 +139,6 @@ func TestSnapshotSource(t *testing.T) {
},
notError: false,
},
{
name: "failed to set policy",
args: []mockArgs{
{methodName: "LoadSnapshot", returns: []interface{}{manifest, nil}},
{methodName: "SaveSnapshot", returns: []interface{}{manifest.ID, nil}},
{methodName: "TreeForSource", returns: []interface{}{nil, nil}},
{methodName: "ApplyRetentionPolicy", returns: []interface{}{nil, nil}},
{methodName: "SetPolicy", returns: []interface{}{errors.New("failed to set policy")}},
{methodName: "Upload", returns: []interface{}{manifest, nil}},
{methodName: "Flush", returns: []interface{}{nil}},
},
notError: false,
},
{
name: "failed to upload snapshot",
args: []mockArgs{
+4 -4
View File
@@ -177,9 +177,9 @@ func (kp *kopiaProvider) RunRestore(
"volumePath": volumePath,
})
repoWriter := kopia.NewShimRepo(kp.bkRepo)
prorgess := new(kopia.Progress)
prorgess.InitThrottle(restoreProgressCheckInterval)
prorgess.Updater = updater
progress := new(kopia.Progress)
progress.InitThrottle(restoreProgressCheckInterval)
progress.Updater = updater
restoreCancel := make(chan struct{})
quit := make(chan struct{})
@@ -193,7 +193,7 @@ func (kp *kopiaProvider) RunRestore(
close(quit)
}()
size, fileCount, err := RestoreFunc(ctx, repoWriter, prorgess, snapshotID, volumePath, log, restoreCancel)
size, fileCount, err := RestoreFunc(ctx, repoWriter, progress, snapshotID, volumePath, log, restoreCancel)
if err != nil {
return errors.Wrapf(err, "Failed to run kopia restore")
+106 -34
View File
@@ -21,6 +21,8 @@ import (
"github.com/kopia/kopia/repo/logging"
"github.com/sirupsen/logrus"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type kopiaLog struct {
@@ -32,59 +34,129 @@ type kopiaLog struct {
// call the logger in the context to write logs
func SetupKopiaLog(ctx context.Context, logger logrus.FieldLogger) context.Context {
return logging.WithLogger(ctx, func(module string) logging.Logger {
return &kopiaLog{
module: module,
logger: logger,
}
kpLog := &kopiaLog{module, logger}
return zap.New(kpLog).Sugar()
})
}
func (kl *kopiaLog) Debugf(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Debugf(msg, args...)
// Enabled decides whether a given logging level is enabled when logging a message
func (kl *kopiaLog) Enabled(level zapcore.Level) bool {
entry := kl.logger.WithField("null", "null")
switch level {
case zapcore.DebugLevel:
return (entry.Logger.GetLevel() >= logrus.DebugLevel)
case zapcore.InfoLevel:
return (entry.Logger.GetLevel() >= logrus.InfoLevel)
case zapcore.WarnLevel:
return (entry.Logger.GetLevel() >= logrus.WarnLevel)
case zapcore.ErrorLevel:
return (entry.Logger.GetLevel() >= logrus.ErrorLevel)
case zapcore.DPanicLevel:
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
case zapcore.PanicLevel:
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
case zapcore.FatalLevel:
return (entry.Logger.GetLevel() >= logrus.FatalLevel)
default:
return false
}
}
func (kl *kopiaLog) Debugw(msg string, keyValuePairs ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.WithFields(getLogFields(keyValuePairs...)).Debug(msg)
// With adds structured context to the Core.
func (kl *kopiaLog) With(fields []zapcore.Field) zapcore.Core {
copied := kl.logrusFields(fields)
return &kopiaLog{
module: kl.module,
logger: kl.logger.WithFields(copied),
}
}
func (kl *kopiaLog) Infof(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Infof(msg, args...)
// Check determines whether the supplied Entry should be logged. If the entry
// should be logged, the Core adds itself to the CheckedEntry and returns the result.
func (kl *kopiaLog) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if kl.Enabled(ent.Level) {
return ce.AddCore(ent, kl)
}
return ce
}
func (kl *kopiaLog) Warnf(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Warnf(msg, args...)
// Write serializes the Entry and any Fields supplied at the log site and writes them to their destination.
func (kl *kopiaLog) Write(ent zapcore.Entry, fields []zapcore.Field) error {
copied := kl.logrusFieldsForWrite(ent, fields)
logger := kl.logger.WithFields(copied)
switch ent.Level {
case zapcore.DebugLevel:
logger.Debug(ent.Message)
case zapcore.InfoLevel:
logger.Info(ent.Message)
case zapcore.WarnLevel:
logger.Warn(ent.Message)
case zapcore.ErrorLevel:
// We see Kopia generates error logs for some normal cases or non-critical
// cases. So Kopia's error logs are regarded as warning logs so that they don't
// affect Velero's workflow.
logger.Warn(ent.Message)
case zapcore.DPanicLevel:
logger.Panic(ent.Message)
case zapcore.PanicLevel:
logger.Panic(ent.Message)
case zapcore.FatalLevel:
logger.Fatal(ent.Message)
}
return nil
}
// We see Kopia generates error logs for some normal cases or non-critical
// cases. So Kopia's error logs are regarded as warning logs so that they don't
// affect Velero's workflow.
func (kl *kopiaLog) Errorf(msg string, args ...interface{}) {
logger := kl.logger.WithFields(logrus.Fields{
"logModule": kl.getLogModule(),
"sublevel": "error",
})
// Sync flushes buffered logs (if any).
func (kl *kopiaLog) Sync() error {
return nil
}
logger.Warnf(msg, args...)
func (kl *kopiaLog) logrusFields(fields []zapcore.Field) logrus.Fields {
if fields == nil {
return logrus.Fields{}
}
m := zapcore.NewMapObjectEncoder()
for _, field := range fields {
field.AddTo(m)
}
return m.Fields
}
func (kl *kopiaLog) getLogModule() string {
return "kopia/" + kl.module
}
func getLogFields(keyValuePairs ...interface{}) map[string]interface{} {
m := map[string]interface{}{}
for i := 0; i+1 < len(keyValuePairs); i += 2 {
s, ok := keyValuePairs[i].(string)
if !ok {
s = "non-string-key"
}
func (kl *kopiaLog) logrusFieldsForWrite(ent zapcore.Entry, fields []zapcore.Field) logrus.Fields {
copied := kl.logrusFields(fields)
m[s] = keyValuePairs[i+1]
copied["logModule"] = kl.getLogModule()
if ent.Caller.Function != "" {
copied["function"] = ent.Caller.Function
}
return m
path := ent.Caller.FullPath()
if path != "undefined" {
copied["path"] = path
}
if ent.LoggerName != "" {
copied["logger name"] = ent.LoggerName
}
if ent.Stack != "" {
copied["stack"] = ent.Stack
}
if ent.Level == zap.ErrorLevel {
copied["sublevel"] = "error"
}
return copied
}
+119 -38
View File
@@ -19,66 +19,147 @@ package logging
import (
"testing"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
"github.com/vmware-tanzu/velero/pkg/test"
)
func TestGetLogFields(t *testing.T) {
func TestEnabled(t *testing.T) {
testCases := []struct {
name string
pairs []interface{}
expected map[string]interface{}
level logrus.Level
zapLevel zapcore.Level
expected bool
}{
{
name: "normal",
pairs: []interface{}{
"fake-key1",
"fake-value1",
"fake-key2",
10,
"fake-key3",
struct{ v int }{v: 10},
name: "check debug again debug",
level: logrus.DebugLevel,
zapLevel: zapcore.DebugLevel,
expected: true,
},
{
name: "check debug again info",
level: logrus.InfoLevel,
zapLevel: zapcore.DebugLevel,
expected: false,
},
{
name: "check info again debug",
level: logrus.DebugLevel,
zapLevel: zapcore.InfoLevel,
expected: true,
},
{
name: "check info again info",
level: logrus.InfoLevel,
zapLevel: zapcore.InfoLevel,
expected: true,
},
{
name: "check info again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.InfoLevel,
expected: false,
},
{
name: "check error again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.ErrorLevel,
expected: true,
},
{
name: "check panic again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.PanicLevel,
expected: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
log := kopiaLog{
logger: test.NewLoggerWithLevel(tc.level),
}
m := log.Enabled(tc.zapLevel)
require.Equal(t, tc.expected, m)
})
}
}
func TestWrite(t *testing.T) {
testCases := []struct {
name string
module string
zapEntry zapcore.Entry
zapFields []zapcore.Field
expected logrus.Fields
}{
{
name: "debug with nil fields",
module: "module-01",
zapEntry: zapcore.Entry{
Level: zapcore.DebugLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"fake-key2": 10,
"fake-key3": struct{ v int }{v: 10},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-01",
},
},
{
name: "non string key",
pairs: []interface{}{
"fake-key1",
"fake-value1",
10,
10,
"fake-key3",
struct{ v int }{v: 10},
name: "error with nil fields",
module: "module-02",
zapEntry: zapcore.Entry{
Level: zapcore.ErrorLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"non-string-key": 10,
"fake-key3": struct{ v int }{v: 10},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-02",
"sublevel": "error",
},
},
{
name: "missing value",
pairs: []interface{}{
"fake-key1",
"fake-value1",
"fake-key2",
10,
"fake-key3",
name: "info with nil string filed",
module: "module-03",
zapEntry: zapcore.Entry{
Level: zapcore.InfoLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"fake-key2": 10,
zapFields: []zapcore.Field{
{
Key: "key-01",
Type: zapcore.StringType,
String: "value-01",
},
},
expected: logrus.Fields{
"logModule": "kopia/module-03",
"key-01": "value-01",
},
},
{
name: "info with logger name",
module: "module-04",
zapEntry: zapcore.Entry{
Level: zapcore.InfoLevel,
LoggerName: "logger-name-01",
},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-04",
"logger name": "logger-name-01",
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
m := getLogFields(tc.pairs...)
log := kopiaLog{
module: tc.module,
logger: test.NewLogger(),
}
m := log.logrusFieldsForWrite(tc.zapEntry, tc.zapFields)
require.Equal(t, tc.expected, m)
})