Fix most remaining wsl lint errors (#656)
* Fix wsl lint errors in pkg package * Fix wsl lint errors in most of internal package Leave some sub-packages out that have higher churn at the moment.
This commit is contained in:
parent
02c2b0b4d6
commit
09cc2769d9
@ -8,14 +8,17 @@ type StringConfigurer interface {
|
|||||||
// map[string]string matching type.
|
// map[string]string matching type.
|
||||||
func UnionStringConfigs(cfgs ...StringConfigurer) (map[string]string, error) {
|
func UnionStringConfigs(cfgs ...StringConfigurer) (map[string]string, error) {
|
||||||
union := map[string]string{}
|
union := map[string]string{}
|
||||||
|
|
||||||
for _, cfg := range cfgs {
|
for _, cfg := range cfgs {
|
||||||
c, err := cfg.StringConfig()
|
c, err := cfg.StringConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range c {
|
for k, v := range c {
|
||||||
union[k] = v
|
union[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return union, nil
|
return union, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ func (e Err) Format(s fmt.State, verb rune) {
|
|||||||
f.Format(s, verb)
|
f.Format(s, verb)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formatting magic courtesy of github.com/pkg/errors.
|
// Formatting magic courtesy of github.com/pkg/errors.
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -50,6 +51,7 @@ func (e Err) Format(s fmt.State, verb rune) {
|
|||||||
fmt.Fprintf(s, "%+v\n", e.Cause())
|
fmt.Fprintf(s, "%+v\n", e.Cause())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case 's', 'q':
|
case 's', 'q':
|
||||||
// nolint:errcheck
|
// nolint:errcheck
|
||||||
|
|||||||
@ -39,6 +39,7 @@ func (suite *ErrorsUnitSuite) TestPropagatesIs() {
|
|||||||
err := assert.AnError
|
err := assert.AnError
|
||||||
te := testErr{*common.EncapsulateError(err)}
|
te := testErr{*common.EncapsulateError(err)}
|
||||||
te2 := testErr2{*common.EncapsulateError(te)}
|
te2 := testErr2{*common.EncapsulateError(te)}
|
||||||
|
|
||||||
assert.True(suite.T(), errors.Is(te2, err))
|
assert.True(suite.T(), errors.Is(te2, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +47,8 @@ func (suite *ErrorsUnitSuite) TestPropagatesAs() {
|
|||||||
err := assert.AnError
|
err := assert.AnError
|
||||||
te := testErr{*common.EncapsulateError(err)}
|
te := testErr{*common.EncapsulateError(err)}
|
||||||
te2 := testErr2{*common.EncapsulateError(te)}
|
te2 := testErr2{*common.EncapsulateError(te)}
|
||||||
var tmp testErr
|
|
||||||
|
tmp := testErr{}
|
||||||
assert.True(suite.T(), errors.As(te2, &tmp))
|
assert.True(suite.T(), errors.As(te2, &tmp))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,14 +56,16 @@ func (suite *ErrorsUnitSuite) TestAs() {
|
|||||||
err := assert.AnError
|
err := assert.AnError
|
||||||
te := testErr{*common.EncapsulateError(err)}
|
te := testErr{*common.EncapsulateError(err)}
|
||||||
te2 := testErr2{*common.EncapsulateError(te)}
|
te2 := testErr2{*common.EncapsulateError(te)}
|
||||||
var tmp testErr2
|
|
||||||
|
tmp := testErr2{}
|
||||||
assert.True(suite.T(), errors.As(te2, &tmp))
|
assert.True(suite.T(), errors.As(te2, &tmp))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ErrorsUnitSuite) TestAsIsUnique() {
|
func (suite *ErrorsUnitSuite) TestAsIsUnique() {
|
||||||
err := assert.AnError
|
err := assert.AnError
|
||||||
te := testErr{*common.EncapsulateError(err)}
|
te := testErr{*common.EncapsulateError(err)}
|
||||||
var tmp testErr2
|
|
||||||
|
tmp := testErr2{}
|
||||||
assert.False(suite.T(), errors.As(te, &tmp))
|
assert.False(suite.T(), errors.As(te, &tmp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ func ContainsString(super []string, sub string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,5 +17,6 @@ func First(vs ...string) string {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ func (suite *CommonSlicesSuite) TestContainsString() {
|
|||||||
target := "fnords"
|
target := "fnords"
|
||||||
good := []string{"fnords"}
|
good := []string{"fnords"}
|
||||||
bad := []string{"foo", "bar"}
|
bad := []string{"foo", "bar"}
|
||||||
|
|
||||||
assert.True(t, common.ContainsString(good, target))
|
assert.True(t, common.ContainsString(good, target))
|
||||||
assert.False(t, common.ContainsString(bad, target))
|
assert.False(t, common.ContainsString(bad, target))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,13 +34,16 @@ func ParseTime(s string) (time.Time, error) {
|
|||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return time.Time{}, errors.New("cannot interpret an empty string as time.Time")
|
return time.Time{}, errors.New("cannot interpret an empty string as time.Time")
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := time.Parse(StandardTimeFormat, s)
|
t, err := time.Parse(StandardTimeFormat, s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return t.UTC(), nil
|
return t.UTC(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err = time.Parse(SimpleDateTimeFormat, s)
|
t, err = time.Parse(SimpleDateTimeFormat, s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return t.UTC(), nil
|
return t.UTC(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return time.Time{}, errors.New("unable to format time string: " + s)
|
return time.Time{}, errors.New("unable to format time string: " + s)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/internal/connector"
|
"github.com/alcionai/corso/internal/connector"
|
||||||
"github.com/alcionai/corso/internal/connector/support"
|
"github.com/alcionai/corso/internal/connector/support"
|
||||||
"github.com/alcionai/corso/internal/data"
|
|
||||||
"github.com/alcionai/corso/internal/kopia"
|
"github.com/alcionai/corso/internal/kopia"
|
||||||
"github.com/alcionai/corso/internal/model"
|
"github.com/alcionai/corso/internal/model"
|
||||||
"github.com/alcionai/corso/internal/stats"
|
"github.com/alcionai/corso/internal/stats"
|
||||||
@ -78,13 +77,13 @@ type backupStats struct {
|
|||||||
|
|
||||||
// Run begins a synchronous backup operation.
|
// Run begins a synchronous backup operation.
|
||||||
func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
||||||
// TODO: persist initial state of backupOperation in modelstore
|
|
||||||
|
|
||||||
// persist operation results to the model store on exit
|
|
||||||
var (
|
var (
|
||||||
opStats backupStats
|
opStats backupStats
|
||||||
backupDetails *details.Details
|
backupDetails *details.Details
|
||||||
)
|
)
|
||||||
|
// TODO: persist initial state of backupOperation in modelstore
|
||||||
|
|
||||||
|
// persist operation results to the model store on exit
|
||||||
defer func() {
|
defer func() {
|
||||||
err = op.persistResults(time.Now(), &opStats)
|
err = op.persistResults(time.Now(), &opStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -93,8 +92,8 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
err = op.createBackupModels(ctx, opStats.k.SnapshotID, backupDetails)
|
err = op.createBackupModels(ctx, opStats.k.SnapshotID, backupDetails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// todo: we're not persisting this yet, except for the error shown to the user.
|
||||||
opStats.writeErr = err
|
opStats.writeErr = err
|
||||||
// todo: ^ we're not persisting this yet, except for the error shown to the user.
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -103,14 +102,15 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "connecting to graph api")
|
err = errors.Wrap(err, "connecting to graph api")
|
||||||
opStats.readErr = err
|
opStats.readErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var cs []data.Collection
|
cs, err := gc.ExchangeDataCollection(ctx, op.Selectors)
|
||||||
cs, err = gc.ExchangeDataCollection(ctx, op.Selectors)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "retrieving service data")
|
err = errors.Wrap(err, "retrieving service data")
|
||||||
opStats.readErr = err
|
opStats.readErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +119,10 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "backing up service data")
|
err = errors.Wrap(err, "backing up service data")
|
||||||
opStats.writeErr = err
|
opStats.writeErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
opStats.started = true
|
opStats.started = true
|
||||||
opStats.gc = gc.AwaitStatus()
|
opStats.gc = gc.AwaitStatus()
|
||||||
|
|
||||||
@ -139,6 +141,7 @@ func (op *BackupOperation) persistResults(
|
|||||||
op.Status = Completed
|
op.Status = Completed
|
||||||
if !opStats.started {
|
if !opStats.started {
|
||||||
op.Status = Failed
|
op.Status = Failed
|
||||||
|
|
||||||
return multierror.Append(
|
return multierror.Append(
|
||||||
errors.New("errors prevented the operation from processing"),
|
errors.New("errors prevented the operation from processing"),
|
||||||
opStats.readErr,
|
opStats.readErr,
|
||||||
@ -174,10 +177,12 @@ func (op *BackupOperation) createBackupModels(
|
|||||||
op.Results.ReadWrites,
|
op.Results.ReadWrites,
|
||||||
op.Results.StartAndEndTime,
|
op.Results.StartAndEndTime,
|
||||||
)
|
)
|
||||||
|
|
||||||
err = op.store.Put(ctx, model.BackupSchema, b)
|
err = op.store.Put(ctx, model.BackupSchema, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "creating backup model")
|
return errors.Wrap(err, "creating backup model")
|
||||||
}
|
}
|
||||||
|
|
||||||
op.Results.BackupID = b.ID
|
op.Results.BackupID = b.ID
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -82,6 +82,7 @@ func TestBackupOpIntegrationSuite(t *testing.T) {
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
t.Skip(err)
|
t.Skip(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
suite.Run(t, new(BackupOpIntegrationSuite))
|
suite.Run(t, new(BackupOpIntegrationSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +165,6 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
// need to initialize the repository before we can test connecting to it.
|
// need to initialize the repository before we can test connecting to it.
|
||||||
|
|||||||
@ -63,8 +63,10 @@ func (op operation) validate() error {
|
|||||||
if op.kopia == nil {
|
if op.kopia == nil {
|
||||||
return errors.New("missing kopia connection")
|
return errors.New("missing kopia connection")
|
||||||
}
|
}
|
||||||
|
|
||||||
if op.store == nil {
|
if op.store == nil {
|
||||||
return errors.New("missing modelstore")
|
return errors.New("missing modelstore")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ func (suite *OperationSuite) TestNewOperation() {
|
|||||||
func (suite *OperationSuite) TestOperation_Validate() {
|
func (suite *OperationSuite) TestOperation_Validate() {
|
||||||
kwStub := &kopia.Wrapper{}
|
kwStub := &kopia.Wrapper{}
|
||||||
swStub := &store.Wrapper{}
|
swStub := &store.Wrapper{}
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
kw *kopia.Wrapper
|
kw *kopia.Wrapper
|
||||||
|
|||||||
@ -81,16 +81,14 @@ type restoreStats struct {
|
|||||||
// Run begins a synchronous restore operation.
|
// Run begins a synchronous restore operation.
|
||||||
func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
||||||
// TODO: persist initial state of restoreOperation in modelstore
|
// TODO: persist initial state of restoreOperation in modelstore
|
||||||
|
|
||||||
// persist operation results to the model store on exit
|
// persist operation results to the model store on exit
|
||||||
opStats := restoreStats{}
|
opStats := restoreStats{}
|
||||||
|
// TODO: persist results?
|
||||||
defer func() {
|
defer func() {
|
||||||
err = op.persistResults(time.Now(), &opStats)
|
err = op.persistResults(time.Now(), &opStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: persist results?
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// retrieve the restore point details
|
// retrieve the restore point details
|
||||||
@ -98,6 +96,7 @@ func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "getting backup details for restore")
|
err = errors.Wrap(err, "getting backup details for restore")
|
||||||
opStats.readErr = err
|
opStats.readErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,15 +115,19 @@ func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
|||||||
// todo: use path pkg for this
|
// todo: use path pkg for this
|
||||||
fdsPaths := fds.Paths()
|
fdsPaths := fds.Paths()
|
||||||
paths := make([][]string, len(fdsPaths))
|
paths := make([][]string, len(fdsPaths))
|
||||||
|
|
||||||
for i := range fdsPaths {
|
for i := range fdsPaths {
|
||||||
paths[i] = strings.Split(fdsPaths[i], "/")
|
paths[i] = strings.Split(fdsPaths[i], "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dcs, err := op.kopia.RestoreMultipleItems(ctx, b.SnapshotID, paths)
|
dcs, err := op.kopia.RestoreMultipleItems(ctx, b.SnapshotID, paths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "retrieving service data")
|
err = errors.Wrap(err, "retrieving service data")
|
||||||
opStats.readErr = err
|
opStats.readErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
opStats.cs = dcs
|
opStats.cs = dcs
|
||||||
|
|
||||||
// restore those collections using graph
|
// restore those collections using graph
|
||||||
@ -132,6 +135,7 @@ func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "connecting to graph api")
|
err = errors.Wrap(err, "connecting to graph api")
|
||||||
opStats.writeErr = err
|
opStats.writeErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,8 +143,10 @@ func (op *RestoreOperation) Run(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "restoring service data")
|
err = errors.Wrap(err, "restoring service data")
|
||||||
opStats.writeErr = err
|
opStats.writeErr = err
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
opStats.started = true
|
opStats.started = true
|
||||||
opStats.gc = gc.AwaitStatus()
|
opStats.gc = gc.AwaitStatus()
|
||||||
logger.Ctx(ctx).Debug(gc.PrintableStatus())
|
logger.Ctx(ctx).Debug(gc.PrintableStatus())
|
||||||
@ -157,8 +163,10 @@ func (op *RestoreOperation) persistResults(
|
|||||||
op.Results.CompletedAt = time.Now()
|
op.Results.CompletedAt = time.Now()
|
||||||
|
|
||||||
op.Status = Completed
|
op.Status = Completed
|
||||||
|
|
||||||
if !opStats.started {
|
if !opStats.started {
|
||||||
op.Status = Failed
|
op.Status = Failed
|
||||||
|
|
||||||
return multierror.Append(
|
return multierror.Append(
|
||||||
errors.New("errors prevented the operation from processing"),
|
errors.New("errors prevented the operation from processing"),
|
||||||
opStats.readErr,
|
opStats.readErr,
|
||||||
|
|||||||
@ -92,6 +92,7 @@ func TestRestoreOpIntegrationSuite(t *testing.T) {
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
t.Skip(err)
|
t.Skip(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
suite.Run(t, new(RestoreOpIntegrationSuite))
|
suite.Run(t, new(RestoreOpIntegrationSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,16 +111,19 @@ func (suite *RestoreOpIntegrationSuite) SetupSuite() {
|
|||||||
|
|
||||||
k := kopia.NewConn(st)
|
k := kopia.NewConn(st)
|
||||||
require.NoError(t, k.Initialize(ctx))
|
require.NoError(t, k.Initialize(ctx))
|
||||||
|
|
||||||
suite.kopiaCloser = func(ctx context.Context) {
|
suite.kopiaCloser = func(ctx context.Context) {
|
||||||
k.Close(ctx)
|
k.Close(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
kw, err := kopia.NewWrapper(k)
|
kw, err := kopia.NewWrapper(k)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
suite.kw = kw
|
suite.kw = kw
|
||||||
|
|
||||||
ms, err := kopia.NewModelStore(k)
|
ms, err := kopia.NewModelStore(k)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
suite.ms = ms
|
suite.ms = ms
|
||||||
|
|
||||||
sw := store.NewKopiaStore(ms)
|
sw := store.NewKopiaStore(ms)
|
||||||
@ -148,9 +152,11 @@ func (suite *RestoreOpIntegrationSuite) TearDownSuite() {
|
|||||||
if suite.ms != nil {
|
if suite.ms != nil {
|
||||||
suite.ms.Close(ctx)
|
suite.ms.Close(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if suite.kw != nil {
|
if suite.kw != nil {
|
||||||
suite.kw.Close(ctx)
|
suite.kw.Close(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if suite.kopiaCloser != nil {
|
if suite.kopiaCloser != nil {
|
||||||
suite.kopiaCloser(ctx)
|
suite.kopiaCloser(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,5 +28,6 @@ func NewM365Account(t *testing.T) account.Account {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t, err, "initializing account")
|
require.NoError(t, err, "initializing account")
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ func StubRootCmd(args ...string) *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
c.SetArgs(args)
|
c.SetArgs(args)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,10 +39,12 @@ func cloneTestConfig() map[string]string {
|
|||||||
if testConfig == nil {
|
if testConfig == nil {
|
||||||
return map[string]string{}
|
return map[string]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
clone := map[string]string{}
|
clone := map[string]string{}
|
||||||
for k, v := range testConfig {
|
for k, v := range testConfig {
|
||||||
clone[k] = v
|
clone[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +57,6 @@ func NewTestViper() (*viper.Viper, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Or use a custom file location
|
// Or use a custom file location
|
||||||
fileName := path.Base(configFilePath)
|
|
||||||
ext := path.Ext(configFilePath)
|
ext := path.Ext(configFilePath)
|
||||||
if len(ext) == 0 {
|
if len(ext) == 0 {
|
||||||
return nil, errors.New("corso_test requires an extension")
|
return nil, errors.New("corso_test requires an extension")
|
||||||
@ -64,6 +65,8 @@ func NewTestViper() (*viper.Viper, error) {
|
|||||||
vpr.SetConfigFile(configFilePath)
|
vpr.SetConfigFile(configFilePath)
|
||||||
vpr.AddConfigPath(path.Dir(configFilePath))
|
vpr.AddConfigPath(path.Dir(configFilePath))
|
||||||
vpr.SetConfigType(ext[1:])
|
vpr.SetConfigType(ext[1:])
|
||||||
|
|
||||||
|
fileName := path.Base(configFilePath)
|
||||||
fileName = strings.TrimSuffix(fileName, ext)
|
fileName = strings.TrimSuffix(fileName, ext)
|
||||||
vpr.SetConfigName(fileName)
|
vpr.SetConfigName(fileName)
|
||||||
|
|
||||||
@ -105,9 +108,10 @@ func readTestConfig() (map[string]string, error) {
|
|||||||
vpr.GetString(TestCfgUserID),
|
vpr.GetString(TestCfgUserID),
|
||||||
"lidiah@8qzvrj.onmicrosoft.com",
|
"lidiah@8qzvrj.onmicrosoft.com",
|
||||||
)
|
)
|
||||||
testEnv[EnvCorsoTestConfigFilePath] = os.Getenv(EnvCorsoTestConfigFilePath)
|
|
||||||
|
|
||||||
|
testEnv[EnvCorsoTestConfigFilePath] = os.Getenv(EnvCorsoTestConfigFilePath)
|
||||||
testConfig = testEnv
|
testConfig = testEnv
|
||||||
|
|
||||||
return cloneTestConfig(), nil
|
return cloneTestConfig(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +134,7 @@ func MakeTempTestConfigClone(t *testing.T, overrides map[string]string) (*viper.
|
|||||||
if len(fName) == 0 || fName == "." || fName == "/" {
|
if len(fName) == 0 || fName == "." || fName == "/" {
|
||||||
fName = ".corso_test.toml"
|
fName = ".corso_test.toml"
|
||||||
}
|
}
|
||||||
|
|
||||||
tDir := t.TempDir()
|
tDir := t.TempDir()
|
||||||
tDirFp := path.Join(tDir, fName)
|
tDirFp := path.Join(tDir, fName)
|
||||||
|
|
||||||
@ -137,8 +142,8 @@ func MakeTempTestConfigClone(t *testing.T, overrides map[string]string) (*viper.
|
|||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
vpr := viper.New()
|
|
||||||
ext := path.Ext(fName)
|
ext := path.Ext(fName)
|
||||||
|
vpr := viper.New()
|
||||||
vpr.SetConfigFile(tDirFp)
|
vpr.SetConfigFile(tDirFp)
|
||||||
vpr.AddConfigPath(tDir)
|
vpr.AddConfigPath(tDir)
|
||||||
vpr.SetConfigType(strings.TrimPrefix(ext, "."))
|
vpr.SetConfigType(strings.TrimPrefix(ext, "."))
|
||||||
|
|||||||
@ -10,13 +10,16 @@ import (
|
|||||||
// If any of the env values are zero length, returns an error.
|
// If any of the env values are zero length, returns an error.
|
||||||
func GetRequiredEnvVars(evs ...string) (map[string]string, error) {
|
func GetRequiredEnvVars(evs ...string) (map[string]string, error) {
|
||||||
vals := map[string]string{}
|
vals := map[string]string{}
|
||||||
|
|
||||||
for _, ev := range evs {
|
for _, ev := range evs {
|
||||||
ge := os.Getenv(ev)
|
ge := os.Getenv(ev)
|
||||||
if len(ge) == 0 {
|
if len(ge) == 0 {
|
||||||
return nil, errors.New(ev + " env var required for test suite")
|
return nil, errors.New(ev + " env var required for test suite")
|
||||||
}
|
}
|
||||||
|
|
||||||
vals[ev] = ge
|
vals[ev] = ge
|
||||||
}
|
}
|
||||||
|
|
||||||
return vals, nil
|
return vals, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,14 +28,17 @@ func GetRequiredEnvVars(evs ...string) (map[string]string, error) {
|
|||||||
// If any of the env values are zero length, returns an error.
|
// If any of the env values are zero length, returns an error.
|
||||||
func GetRequiredEnvSls(evs ...[]string) (map[string]string, error) {
|
func GetRequiredEnvSls(evs ...[]string) (map[string]string, error) {
|
||||||
vals := map[string]string{}
|
vals := map[string]string{}
|
||||||
|
|
||||||
for _, ev := range evs {
|
for _, ev := range evs {
|
||||||
r, err := GetRequiredEnvVars(ev...)
|
r, err := GetRequiredEnvVars(ev...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range r {
|
for k, v := range r {
|
||||||
vals[k] = v
|
vals[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vals, nil
|
return vals, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ func TestEnvvarsSuite(t *testing.T) {
|
|||||||
func (suite *EnvvarsTestSuite) TestRunOnAny() {
|
func (suite *EnvvarsTestSuite) TestRunOnAny() {
|
||||||
envVariable := "TEST_ENVVARS_SUITE"
|
envVariable := "TEST_ENVVARS_SUITE"
|
||||||
os.Setenv(envVariable, "1")
|
os.Setenv(envVariable, "1")
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
param string
|
param string
|
||||||
@ -41,5 +42,6 @@ func (suite *EnvvarsTestSuite) TestRunOnAny() {
|
|||||||
test.function(suite.T(), result)
|
test.function(suite.T(), result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Unsetenv(envVariable)
|
os.Unsetenv(envVariable)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,11 +35,13 @@ func RunOnAny(tests ...string) error {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
l += len(os.Getenv(test))
|
l += len(os.Getenv(test))
|
||||||
}
|
}
|
||||||
|
|
||||||
if l == 0 {
|
if l == 0 {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"%s env vars are not flagged for testing",
|
"%s env vars are not flagged for testing",
|
||||||
strings.Join(tests, ", "))
|
strings.Join(tests, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,10 +49,13 @@ func RunOnAny(tests ...string) error {
|
|||||||
func LogTimeOfTest(t *testing.T) string {
|
func LogTimeOfTest(t *testing.T) string {
|
||||||
now := time.Now().UTC().Format(time.RFC3339Nano)
|
now := time.Now().UTC().Format(time.RFC3339Nano)
|
||||||
name := t.Name()
|
name := t.Name()
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
t.Logf("Test run at %s.", now)
|
t.Logf("Test run at %s.", now)
|
||||||
return now
|
return now
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("%s run at %s", name, now)
|
t.Logf("%s run at %s", name, now)
|
||||||
|
|
||||||
return now
|
return now
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,18 +13,24 @@ func LoadAFile(aFile string) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
buffer := make([]byte, 0)
|
buffer := make([]byte, 0)
|
||||||
reader := bufio.NewScanner(f)
|
reader := bufio.NewScanner(f)
|
||||||
|
|
||||||
for reader.Scan() {
|
for reader.Scan() {
|
||||||
temp := reader.Bytes()
|
temp := reader.Bytes()
|
||||||
buffer = append(buffer, temp...)
|
buffer = append(buffer, temp...)
|
||||||
}
|
}
|
||||||
|
|
||||||
aErr := reader.Err()
|
aErr := reader.Err()
|
||||||
if aErr != nil {
|
if aErr != nil {
|
||||||
return nil, aErr
|
return nil, aErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes, nil
|
return bytes, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ var AWSStorageCredEnvs = []string{
|
|||||||
// configs.
|
// configs.
|
||||||
func NewPrefixedS3Storage(t *testing.T) storage.Storage {
|
func NewPrefixedS3Storage(t *testing.T) storage.Storage {
|
||||||
now := LogTimeOfTest(t)
|
now := LogTimeOfTest(t)
|
||||||
|
|
||||||
cfg, err := readTestConfig()
|
cfg, err := readTestConfig()
|
||||||
require.NoError(t, err, "configuring storage from test file")
|
require.NoError(t, err, "configuring storage from test file")
|
||||||
|
|
||||||
@ -39,5 +40,6 @@ func NewPrefixedS3Storage(t *testing.T) storage.Storage {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t, err, "creating storage")
|
require.NoError(t, err, "creating storage")
|
||||||
|
|
||||||
return st
|
return st
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,5 +13,6 @@ import (
|
|||||||
func M365UserID(t *testing.T) string {
|
func M365UserID(t *testing.T) string {
|
||||||
cfg, err := readTestConfig()
|
cfg, err := readTestConfig()
|
||||||
require.NoError(t, err, "retrieving m365 user id from test configuration")
|
require.NoError(t, err, "retrieving m365 user id from test configuration")
|
||||||
|
|
||||||
return cfg[TestCfgUserID]
|
return cfg[TestCfgUserID]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ type Account struct {
|
|||||||
// NewAccount aggregates all the supplied configurations into a single configuration
|
// NewAccount aggregates all the supplied configurations into a single configuration
|
||||||
func NewAccount(p accountProvider, cfgs ...common.StringConfigurer) (Account, error) {
|
func NewAccount(p accountProvider, cfgs ...common.StringConfigurer) (Account, error) {
|
||||||
cs, err := common.UnionStringConfigs(cfgs...)
|
cs, err := common.UnionStringConfigs(cfgs...)
|
||||||
|
|
||||||
return Account{
|
return Account{
|
||||||
Provider: p,
|
Provider: p,
|
||||||
Config: cs,
|
Config: cs,
|
||||||
|
|||||||
@ -32,6 +32,7 @@ func (c M365Config) StringConfig() (map[string]string, error) {
|
|||||||
keyM365ClientSecret: c.ClientSecret,
|
keyM365ClientSecret: c.ClientSecret,
|
||||||
keyM365TenantID: c.TenantID,
|
keyM365TenantID: c.TenantID,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, c.validate()
|
return cfg, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ func (a Account) M365Config() (M365Config, error) {
|
|||||||
c.ClientSecret = a.Config[keyM365ClientSecret]
|
c.ClientSecret = a.Config[keyM365ClientSecret]
|
||||||
c.TenantID = a.Config[keyM365TenantID]
|
c.TenantID = a.Config[keyM365TenantID]
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, c.validate()
|
return c, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,10 +54,12 @@ func (c M365Config) validate() error {
|
|||||||
credentials.ClientSecret: c.ClientSecret,
|
credentials.ClientSecret: c.ClientSecret,
|
||||||
TenantID: c.TenantID,
|
TenantID: c.TenantID,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range check {
|
for k, v := range check {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return errors.Wrap(errMissingRequired, k)
|
return errors.Wrap(errMissingRequired, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,6 +71,7 @@ func PrintAll(ctx context.Context, bs []Backup) {
|
|||||||
for _, b := range bs {
|
for _, b := range bs {
|
||||||
ps = append(ps, print.Printable(b))
|
ps = append(ps, print.Printable(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
print.All(ctx, ps...)
|
print.All(ctx, ps...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +112,7 @@ func (b Backup) Headers() []string {
|
|||||||
func (b Backup) Values() []string {
|
func (b Backup) Values() []string {
|
||||||
errCount := support.GetNumberOfErrors(b.ReadErrors) + support.GetNumberOfErrors(b.WriteErrors)
|
errCount := support.GetNumberOfErrors(b.ReadErrors) + support.GetNumberOfErrors(b.WriteErrors)
|
||||||
status := fmt.Sprintf("%s (%d errors)", b.Status, errCount)
|
status := fmt.Sprintf("%s (%d errors)", b.Status, errCount)
|
||||||
|
|
||||||
return []string{
|
return []string{
|
||||||
common.FormatTime(b.StartedAt),
|
common.FormatTime(b.StartedAt),
|
||||||
string(b.ID),
|
string(b.ID),
|
||||||
|
|||||||
@ -27,6 +27,7 @@ func TestBackupSuite(t *testing.T) {
|
|||||||
func stubBackup(t time.Time) backup.Backup {
|
func stubBackup(t time.Time) backup.Backup {
|
||||||
sel := selectors.NewExchangeBackup()
|
sel := selectors.NewExchangeBackup()
|
||||||
sel.Include(sel.Users(selectors.Any()))
|
sel.Include(sel.Users(selectors.Any()))
|
||||||
|
|
||||||
return backup.Backup{
|
return backup.Backup{
|
||||||
BaseModel: model.BaseModel{
|
BaseModel: model.BaseModel{
|
||||||
ID: model.StableID("id"),
|
ID: model.StableID("id"),
|
||||||
@ -62,14 +63,15 @@ func (suite *BackupSuite) TestBackup_HeadersValues() {
|
|||||||
}
|
}
|
||||||
hs := b.Headers()
|
hs := b.Headers()
|
||||||
assert.Equal(t, expectHs, hs)
|
assert.Equal(t, expectHs, hs)
|
||||||
nowFmt := common.FormatTime(now)
|
|
||||||
|
|
||||||
|
nowFmt := common.FormatTime(now)
|
||||||
expectVs := []string{
|
expectVs := []string{
|
||||||
nowFmt,
|
nowFmt,
|
||||||
"id",
|
"id",
|
||||||
"status (2 errors)",
|
"status (2 errors)",
|
||||||
selectors.All,
|
selectors.All,
|
||||||
}
|
}
|
||||||
|
|
||||||
vs := b.Values()
|
vs := b.Values()
|
||||||
assert.Equal(t, expectVs, vs)
|
assert.Equal(t, expectVs, vs)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ func (dm DetailsModel) PrintEntries(ctx context.Context) {
|
|||||||
for _, de := range dm.Entries {
|
for _, de := range dm.Entries {
|
||||||
ps = append(ps, de)
|
ps = append(ps, de)
|
||||||
}
|
}
|
||||||
|
|
||||||
print.All(ctx, ps...)
|
print.All(ctx, ps...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,9 +34,11 @@ func (dm DetailsModel) PrintEntries(ctx context.Context) {
|
|||||||
func (dm DetailsModel) Paths() []string {
|
func (dm DetailsModel) Paths() []string {
|
||||||
ents := dm.Entries
|
ents := dm.Entries
|
||||||
r := make([]string, len(ents))
|
r := make([]string, len(ents))
|
||||||
|
|
||||||
for i := range ents {
|
for i := range ents {
|
||||||
r[i] = ents[i].RepoRef
|
r[i] = ents[i].RepoRef
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,30 +91,38 @@ func (de DetailsEntry) MinimumPrintable() any {
|
|||||||
// for printing out to a terminal in a columnar display.
|
// for printing out to a terminal in a columnar display.
|
||||||
func (de DetailsEntry) Headers() []string {
|
func (de DetailsEntry) Headers() []string {
|
||||||
hs := []string{"Repo Ref"}
|
hs := []string{"Repo Ref"}
|
||||||
|
|
||||||
if de.ItemInfo.Exchange != nil {
|
if de.ItemInfo.Exchange != nil {
|
||||||
hs = append(hs, de.ItemInfo.Exchange.Headers()...)
|
hs = append(hs, de.ItemInfo.Exchange.Headers()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if de.ItemInfo.Sharepoint != nil {
|
if de.ItemInfo.Sharepoint != nil {
|
||||||
hs = append(hs, de.ItemInfo.Sharepoint.Headers()...)
|
hs = append(hs, de.ItemInfo.Sharepoint.Headers()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if de.ItemInfo.OneDrive != nil {
|
if de.ItemInfo.OneDrive != nil {
|
||||||
hs = append(hs, de.ItemInfo.OneDrive.Headers()...)
|
hs = append(hs, de.ItemInfo.OneDrive.Headers()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hs
|
return hs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns the values matching the Headers list.
|
// Values returns the values matching the Headers list.
|
||||||
func (de DetailsEntry) Values() []string {
|
func (de DetailsEntry) Values() []string {
|
||||||
vs := []string{de.RepoRef}
|
vs := []string{de.RepoRef}
|
||||||
|
|
||||||
if de.ItemInfo.Exchange != nil {
|
if de.ItemInfo.Exchange != nil {
|
||||||
vs = append(vs, de.ItemInfo.Exchange.Values()...)
|
vs = append(vs, de.ItemInfo.Exchange.Values()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if de.ItemInfo.Sharepoint != nil {
|
if de.ItemInfo.Sharepoint != nil {
|
||||||
vs = append(vs, de.ItemInfo.Sharepoint.Values()...)
|
vs = append(vs, de.ItemInfo.Sharepoint.Values()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if de.ItemInfo.OneDrive != nil {
|
if de.ItemInfo.OneDrive != nil {
|
||||||
vs = append(vs, de.ItemInfo.OneDrive.Values()...)
|
vs = append(vs, de.ItemInfo.OneDrive.Values()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vs
|
return vs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,10 @@ func TestOptionsSuite(t *testing.T) {
|
|||||||
|
|
||||||
func (suite *OptionsSuite) TestNewOptions() {
|
func (suite *OptionsSuite) TestNewOptions() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
o1 := control.NewOptions(true)
|
o1 := control.NewOptions(true)
|
||||||
assert.True(t, o1.FailFast, "failFast")
|
assert.True(t, o1.FailFast, "failFast")
|
||||||
|
|
||||||
o2 := control.NewOptions(false)
|
o2 := control.NewOptions(false)
|
||||||
assert.False(t, o2.FailFast, "failFast")
|
assert.False(t, o2.FailFast, "failFast")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ func GetAWS(override map[string]string) AWS {
|
|||||||
if ovr, ok := override[AWSAccessKeyID]; ok && ovr != "" {
|
if ovr, ok := override[AWSAccessKeyID]; ok && ovr != "" {
|
||||||
accessKey = ovr
|
accessKey = ovr
|
||||||
}
|
}
|
||||||
|
|
||||||
secretKey := os.Getenv(AWSSecretAccessKey)
|
secretKey := os.Getenv(AWSSecretAccessKey)
|
||||||
sessToken := os.Getenv(AWSSessionToken)
|
sessToken := os.Getenv(AWSSessionToken)
|
||||||
|
|
||||||
@ -44,10 +45,12 @@ func (c AWS) Validate() error {
|
|||||||
AWSSecretAccessKey: c.SecretKey,
|
AWSSecretAccessKey: c.SecretKey,
|
||||||
AWSSessionToken: c.SessionToken,
|
AWSSessionToken: c.SessionToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range check {
|
for k, v := range check {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return errors.Wrap(errMissingRequired, k)
|
return errors.Wrap(errMissingRequired, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ func GetCorso() Corso {
|
|||||||
// todo (rkeeprs): read from either corso config file or env vars.
|
// todo (rkeeprs): read from either corso config file or env vars.
|
||||||
// https://github.com/alcionai/corso/issues/120
|
// https://github.com/alcionai/corso/issues/120
|
||||||
corsoPasswd := os.Getenv(CorsoPassword)
|
corsoPasswd := os.Getenv(CorsoPassword)
|
||||||
|
|
||||||
return Corso{
|
return Corso{
|
||||||
CorsoPassword: corsoPasswd,
|
CorsoPassword: corsoPasswd,
|
||||||
}
|
}
|
||||||
@ -30,10 +31,12 @@ func (c Corso) Validate() error {
|
|||||||
check := map[string]string{
|
check := map[string]string{
|
||||||
CorsoPassword: c.CorsoPassword,
|
CorsoPassword: c.CorsoPassword,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range check {
|
for k, v := range check {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return errors.Wrap(errMissingRequired, k)
|
return errors.Wrap(errMissingRequired, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,10 +33,12 @@ func (c M365) Validate() error {
|
|||||||
ClientID: c.ClientID,
|
ClientID: c.ClientID,
|
||||||
ClientSecret: c.ClientSecret,
|
ClientSecret: c.ClientSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range check {
|
for k, v := range check {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return errors.Wrap(errMissingRequired, k)
|
return errors.Wrap(errMissingRequired, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,7 @@ func NewIn(negate bool, category any, substr string) Filter {
|
|||||||
// Checks whether the filter matches the input
|
// Checks whether the filter matches the input
|
||||||
func (f Filter) Matches(input string) bool {
|
func (f Filter) Matches(input string) bool {
|
||||||
var cmp func(string, string) bool
|
var cmp func(string, string) bool
|
||||||
|
|
||||||
switch f.Comparator {
|
switch f.Comparator {
|
||||||
case Equal:
|
case Equal:
|
||||||
cmp = equals
|
cmp = equals
|
||||||
@ -97,10 +98,12 @@ func (f Filter) Matches(input string) bool {
|
|||||||
case In:
|
case In:
|
||||||
cmp = in
|
cmp = in
|
||||||
}
|
}
|
||||||
|
|
||||||
result := cmp(f.Target, norm(input))
|
result := cmp(f.Target, norm(input))
|
||||||
if f.Negate {
|
if f.Negate {
|
||||||
result = !result
|
result = !result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,14 +68,17 @@ func singleton(level logLevel) *zap.SugaredLogger {
|
|||||||
lgr *zap.Logger
|
lgr *zap.Logger
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if level != Production {
|
if level != Production {
|
||||||
cfg := zap.NewDevelopmentConfig()
|
cfg := zap.NewDevelopmentConfig()
|
||||||
|
|
||||||
switch level {
|
switch level {
|
||||||
case Info:
|
case Info:
|
||||||
cfg.Level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
|
cfg.Level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
|
||||||
case Warn:
|
case Warn:
|
||||||
cfg.Level = zap.NewAtomicLevelAt(zapcore.WarnLevel)
|
cfg.Level = zap.NewAtomicLevelAt(zapcore.WarnLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
lgr, err = cfg.Build()
|
lgr, err = cfg.Build()
|
||||||
} else {
|
} else {
|
||||||
lgr, err = zap.NewProduction()
|
lgr, err = zap.NewProduction()
|
||||||
@ -87,6 +90,7 @@ func singleton(level logLevel) *zap.SugaredLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loggerton = lgr.Sugar()
|
loggerton = lgr.Sugar()
|
||||||
|
|
||||||
return loggerton
|
return loggerton
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +130,7 @@ func Seed(ctx context.Context) (ctxOut context.Context, zsl *zap.SugaredLogger)
|
|||||||
}
|
}
|
||||||
|
|
||||||
level = levelOf(levelString)
|
level = levelOf(levelString)
|
||||||
|
|
||||||
return // return values handled in defer
|
return // return values handled in defer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +140,7 @@ func Ctx(ctx context.Context) *zap.SugaredLogger {
|
|||||||
if l == nil {
|
if l == nil {
|
||||||
return singleton(levelOf(llFlag))
|
return singleton(levelOf(llFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.(*zap.SugaredLogger)
|
return l.(*zap.SugaredLogger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,5 +154,6 @@ func levelOf(lvl string) logLevel {
|
|||||||
case "error":
|
case "error":
|
||||||
return Production
|
return Production
|
||||||
}
|
}
|
||||||
|
|
||||||
return Info
|
return Info
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,6 +70,7 @@ func Initialize(
|
|||||||
dataLayer: w,
|
dataLayer: w,
|
||||||
modelStore: ms,
|
modelStore: ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +110,7 @@ func Connect(
|
|||||||
dataLayer: w,
|
dataLayer: w,
|
||||||
modelStore: ms,
|
modelStore: ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +118,7 @@ func (r *Repository) Close(ctx context.Context) error {
|
|||||||
if r.dataLayer != nil {
|
if r.dataLayer != nil {
|
||||||
err := r.dataLayer.Close(ctx)
|
err := r.dataLayer.Close(ctx)
|
||||||
r.dataLayer = nil
|
r.dataLayer = nil
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "closing corso DataLayer")
|
return errors.Wrap(err, "closing corso DataLayer")
|
||||||
}
|
}
|
||||||
@ -124,8 +127,10 @@ func (r *Repository) Close(ctx context.Context) error {
|
|||||||
if r.modelStore == nil {
|
if r.modelStore == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := r.modelStore.Close(ctx)
|
err := r.modelStore.Close(ctx)
|
||||||
r.modelStore = nil
|
r.modelStore = nil
|
||||||
|
|
||||||
return errors.Wrap(err, "closing corso ModelStore")
|
return errors.Wrap(err, "closing corso ModelStore")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,5 +196,6 @@ func (r Repository) DeleteBackup(ctx context.Context, id model.StableID) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sw := store.NewKopiaStore(r.modelStore)
|
sw := store.NewKopiaStore(r.modelStore)
|
||||||
|
|
||||||
return sw.DeleteBackup(ctx, id)
|
return sw.DeleteBackup(ctx, id)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,6 +97,7 @@ func TestRepositoryIntegrationSuite(t *testing.T) {
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
t.Skip(err)
|
t.Skip(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
suite.Run(t, new(RepositoryIntegrationSuite))
|
suite.Run(t, new(RepositoryIntegrationSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ func NewExchangeBackup() *ExchangeBackup {
|
|||||||
newSelector(ServiceExchange),
|
newSelector(ServiceExchange),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &src
|
return &src
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +50,9 @@ func (s Selector) ToExchangeBackup() (*ExchangeBackup, error) {
|
|||||||
if s.Service != ServiceExchange {
|
if s.Service != ServiceExchange {
|
||||||
return nil, badCastErr(ServiceExchange, s.Service)
|
return nil, badCastErr(ServiceExchange, s.Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
src := ExchangeBackup{exchange{s}}
|
src := ExchangeBackup{exchange{s}}
|
||||||
|
|
||||||
return &src, nil
|
return &src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +63,7 @@ func NewExchangeRestore() *ExchangeRestore {
|
|||||||
newSelector(ServiceExchange),
|
newSelector(ServiceExchange),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &src
|
return &src
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +73,9 @@ func (s Selector) ToExchangeRestore() (*ExchangeRestore, error) {
|
|||||||
if s.Service != ServiceExchange {
|
if s.Service != ServiceExchange {
|
||||||
return nil, badCastErr(ServiceExchange, s.Service)
|
return nil, badCastErr(ServiceExchange, s.Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
src := ExchangeRestore{exchange{s}}
|
src := ExchangeRestore{exchange{s}}
|
||||||
|
|
||||||
return &src, nil
|
return &src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +169,7 @@ func (s *exchange) Contacts(users, folders, contacts []string) []ExchangeScope {
|
|||||||
folders = normalize(folders)
|
folders = normalize(folders)
|
||||||
contacts = normalize(contacts)
|
contacts = normalize(contacts)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
for _, f := range folders {
|
for _, f := range folders {
|
||||||
scopes = append(
|
scopes = append(
|
||||||
@ -171,6 +178,7 @@ func (s *exchange) Contacts(users, folders, contacts []string) []ExchangeScope {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,12 +191,14 @@ func (s *exchange) ContactFolders(users, folders []string) []ExchangeScope {
|
|||||||
users = normalize(users)
|
users = normalize(users)
|
||||||
folders = normalize(folders)
|
folders = normalize(folders)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](u, Group, ExchangeContactFolder, folders),
|
makeScope[ExchangeScope](u, Group, ExchangeContactFolder, folders),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,12 +211,14 @@ func (s *exchange) Events(users, events []string) []ExchangeScope {
|
|||||||
users = normalize(users)
|
users = normalize(users)
|
||||||
events = normalize(events)
|
events = normalize(events)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](u, Item, ExchangeEvent, events),
|
makeScope[ExchangeScope](u, Item, ExchangeEvent, events),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +232,7 @@ func (s *exchange) Mails(users, folders, mails []string) []ExchangeScope {
|
|||||||
folders = normalize(folders)
|
folders = normalize(folders)
|
||||||
mails = normalize(mails)
|
mails = normalize(mails)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
for _, f := range folders {
|
for _, f := range folders {
|
||||||
scopes = append(
|
scopes = append(
|
||||||
@ -228,6 +241,7 @@ func (s *exchange) Mails(users, folders, mails []string) []ExchangeScope {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,12 +254,14 @@ func (s *exchange) MailFolders(users, folders []string) []ExchangeScope {
|
|||||||
users = normalize(users)
|
users = normalize(users)
|
||||||
folders = normalize(folders)
|
folders = normalize(folders)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
scopes = append(
|
scopes = append(
|
||||||
scopes,
|
scopes,
|
||||||
makeScope[ExchangeScope](u, Group, ExchangeMailFolder, folders),
|
makeScope[ExchangeScope](u, Group, ExchangeMailFolder, folders),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +273,13 @@ func (s *exchange) MailFolders(users, folders []string) []ExchangeScope {
|
|||||||
func (s *exchange) Users(users []string) []ExchangeScope {
|
func (s *exchange) Users(users []string) []ExchangeScope {
|
||||||
users = normalize(users)
|
users = normalize(users)
|
||||||
scopes := []ExchangeScope{}
|
scopes := []ExchangeScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
scopes = append(scopes, makeScope[ExchangeScope](u, Group, ExchangeContactFolder, Any()))
|
scopes = append(scopes, makeScope[ExchangeScope](u, Group, ExchangeContactFolder, Any()))
|
||||||
scopes = append(scopes, makeScope[ExchangeScope](u, Item, ExchangeEvent, Any()))
|
scopes = append(scopes, makeScope[ExchangeScope](u, Item, ExchangeEvent, Any()))
|
||||||
scopes = append(scopes, makeScope[ExchangeScope](u, Group, ExchangeMailFolder, Any()))
|
scopes = append(scopes, makeScope[ExchangeScope](u, Group, ExchangeMailFolder, Any()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,6 +345,7 @@ func (d ExchangeDestination) GetOrDefault(cat exchangeCategory, current string)
|
|||||||
if !ok {
|
if !ok {
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,11 +355,14 @@ func (d ExchangeDestination) Set(cat exchangeCategory, dest string) error {
|
|||||||
if len(dest) == 0 {
|
if len(dest) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := cat.String()
|
cs := cat.String()
|
||||||
if curr, ok := d[cs]; ok {
|
if curr, ok := d[cs]; ok {
|
||||||
return existingDestinationErr(cs, curr)
|
return existingDestinationErr(cs, curr)
|
||||||
}
|
}
|
||||||
|
|
||||||
d[cs] = dest
|
d[cs] = dest
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,6 +446,7 @@ func (ec exchangeCategory) leafCat() categorizer {
|
|||||||
case ExchangeMail, ExchangeMailFolder:
|
case ExchangeMail, ExchangeMailFolder:
|
||||||
return ExchangeMail
|
return ExchangeMail
|
||||||
}
|
}
|
||||||
|
|
||||||
return ec
|
return ec
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,6 +474,7 @@ func (ec exchangeCategory) pathValues(path []string) map[categorizer]string {
|
|||||||
if len(path) < 2 {
|
if len(path) < 2 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
m[ExchangeUser] = path[1]
|
m[ExchangeUser] = path[1]
|
||||||
/*
|
/*
|
||||||
TODO/Notice:
|
TODO/Notice:
|
||||||
@ -465,20 +489,26 @@ func (ec exchangeCategory) pathValues(path []string) map[categorizer]string {
|
|||||||
if len(path) < 5 {
|
if len(path) < 5 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
m[ExchangeContactFolder] = path[3]
|
m[ExchangeContactFolder] = path[3]
|
||||||
m[ExchangeContact] = path[4]
|
m[ExchangeContact] = path[4]
|
||||||
|
|
||||||
case ExchangeEvent:
|
case ExchangeEvent:
|
||||||
if len(path) < 4 {
|
if len(path) < 4 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
m[ExchangeEvent] = path[3]
|
m[ExchangeEvent] = path[3]
|
||||||
|
|
||||||
case ExchangeMail:
|
case ExchangeMail:
|
||||||
if len(path) < 5 {
|
if len(path) < 5 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
m[ExchangeMailFolder] = path[3]
|
m[ExchangeMailFolder] = path[3]
|
||||||
m[ExchangeMail] = path[4]
|
m[ExchangeMail] = path[4]
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,18 +634,23 @@ func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool {
|
|||||||
if info == nil {
|
if info == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// the scope must define targets to match on
|
// the scope must define targets to match on
|
||||||
filterCat := s.FilterCategory()
|
filterCat := s.FilterCategory()
|
||||||
targets := s.Get(filterCat)
|
targets := s.Get(filterCat)
|
||||||
|
|
||||||
if len(targets) == 0 {
|
if len(targets) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if targets[0] == AnyTgt {
|
if targets[0] == AnyTgt {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if targets[0] == NoneTgt {
|
if targets[0] == NoneTgt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// any of the targets for a given info filter may succeed.
|
// any of the targets for a given info filter may succeed.
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
switch filterCat {
|
switch filterCat {
|
||||||
@ -637,5 +672,6 @@ func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -281,13 +281,16 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() {
|
|||||||
|
|
||||||
for _, scope := range scopes {
|
for _, scope := range scopes {
|
||||||
assert.Contains(t, join(u1, u2), scope[ExchangeUser.String()])
|
assert.Contains(t, join(u1, u2), scope[ExchangeUser.String()])
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeContactFolder.String() {
|
if scope[scopeKeyCategory] == ExchangeContactFolder.String() {
|
||||||
assert.Equal(t, scope[ExchangeContact.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeContact.String()], AnyTgt)
|
||||||
assert.Equal(t, scope[ExchangeContactFolder.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeContactFolder.String()], AnyTgt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeEvent.String() {
|
if scope[scopeKeyCategory] == ExchangeEvent.String() {
|
||||||
assert.Equal(t, scope[ExchangeEvent.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeEvent.String()], AnyTgt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeMailFolder.String() {
|
if scope[scopeKeyCategory] == ExchangeMailFolder.String() {
|
||||||
assert.Equal(t, scope[ExchangeMail.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeMail.String()], AnyTgt)
|
||||||
assert.Equal(t, scope[ExchangeMailFolder.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeMailFolder.String()], AnyTgt)
|
||||||
@ -310,13 +313,16 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() {
|
|||||||
|
|
||||||
for _, scope := range scopes {
|
for _, scope := range scopes {
|
||||||
assert.Contains(t, join(u1, u2), scope[ExchangeUser.String()])
|
assert.Contains(t, join(u1, u2), scope[ExchangeUser.String()])
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeContactFolder.String() {
|
if scope[scopeKeyCategory] == ExchangeContactFolder.String() {
|
||||||
assert.Equal(t, scope[ExchangeContact.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeContact.String()], AnyTgt)
|
||||||
assert.Equal(t, scope[ExchangeContactFolder.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeContactFolder.String()], AnyTgt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeEvent.String() {
|
if scope[scopeKeyCategory] == ExchangeEvent.String() {
|
||||||
assert.Equal(t, scope[ExchangeEvent.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeEvent.String()], AnyTgt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope[scopeKeyCategory] == ExchangeMailFolder.String() {
|
if scope[scopeKeyCategory] == ExchangeMailFolder.String() {
|
||||||
assert.Equal(t, scope[ExchangeMail.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeMail.String()], AnyTgt)
|
||||||
assert.Equal(t, scope[ExchangeMailFolder.String()], AnyTgt)
|
assert.Equal(t, scope[ExchangeMailFolder.String()], AnyTgt)
|
||||||
@ -379,6 +385,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeBackup_Scopes() {
|
|||||||
|
|
||||||
scopes := eb.Scopes()
|
scopes := eb.Scopes()
|
||||||
assert.Len(suite.T(), scopes, 3)
|
assert.Len(suite.T(), scopes, 3)
|
||||||
|
|
||||||
for _, sc := range scopes {
|
for _, sc := range scopes {
|
||||||
cat := sc.Category()
|
cat := sc.Category()
|
||||||
suite.T().Run(cat.String(), func(t *testing.T) {
|
suite.T().Run(cat.String(), func(t *testing.T) {
|
||||||
@ -424,6 +431,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeBackup_DiscreteScopes() {
|
|||||||
expect: Any(),
|
expect: Any(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
eb := NewExchangeBackup()
|
eb := NewExchangeBackup()
|
||||||
@ -515,7 +523,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() {
|
|||||||
ExchangeMailFolder,
|
ExchangeMailFolder,
|
||||||
ExchangeUser,
|
ExchangeUser,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.T().Run(test.String(), func(t *testing.T) {
|
suite.T().Run(test.String(), func(t *testing.T) {
|
||||||
for _, sc := range scopes {
|
for _, sc := range scopes {
|
||||||
@ -538,10 +545,12 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() {
|
|||||||
|
|
||||||
func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
|
func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() {
|
||||||
es := NewExchangeRestore()
|
es := NewExchangeRestore()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sender = "smarf@2many.cooks"
|
sender = "smarf@2many.cooks"
|
||||||
subject = "I have seen the fnords!"
|
subject = "I have seen the fnords!"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
epoch = time.Time{}
|
epoch = time.Time{}
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
@ -590,6 +599,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() {
|
|||||||
fld = "mailFolder"
|
fld = "mailFolder"
|
||||||
mail = "mailID"
|
mail = "mailID"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
path = []string{"tid", usr, "mail", fld, mail}
|
path = []string{"tid", usr, "mail", fld, mail}
|
||||||
es = NewExchangeRestore()
|
es = NewExchangeRestore()
|
||||||
@ -684,21 +694,26 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() {
|
|||||||
Entries: []details.DetailsEntry{},
|
Entries: []details.DetailsEntry{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range refs {
|
for _, r := range refs {
|
||||||
deets.Entries = append(deets.Entries, details.DetailsEntry{
|
deets.Entries = append(deets.Entries, details.DetailsEntry{
|
||||||
RepoRef: r,
|
RepoRef: r,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return deets
|
return deets
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
contact = "tid/uid/contact/cfld/cid"
|
contact = "tid/uid/contact/cfld/cid"
|
||||||
event = "tid/uid/event/eid"
|
event = "tid/uid/event/eid"
|
||||||
mail = "tid/uid/mail/mfld/mid"
|
mail = "tid/uid/mail/mfld/mid"
|
||||||
)
|
)
|
||||||
|
|
||||||
arr := func(s ...string) []string {
|
arr := func(s ...string) []string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
deets *details.Details
|
deets *details.Details
|
||||||
@ -837,19 +852,24 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
|
|||||||
events = es.Events(Any(), Any())
|
events = es.Events(Any(), Any())
|
||||||
mail = es.MailFolders(Any(), Any())
|
mail = es.MailFolders(Any(), Any())
|
||||||
)
|
)
|
||||||
|
|
||||||
type expect struct {
|
type expect struct {
|
||||||
contact int
|
contact int
|
||||||
event int
|
event int
|
||||||
mail int
|
mail int
|
||||||
}
|
}
|
||||||
|
|
||||||
type input []scope
|
type input []scope
|
||||||
|
|
||||||
makeInput := func(es ...[]ExchangeScope) []scope {
|
makeInput := func(es ...[]ExchangeScope) []scope {
|
||||||
mss := []scope{}
|
mss := []scope{}
|
||||||
|
|
||||||
for _, sl := range es {
|
for _, sl := range es {
|
||||||
for _, s := range sl {
|
for _, s := range sl {
|
||||||
mss = append(mss, scope(s))
|
mss = append(mss, scope(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mss
|
return mss
|
||||||
}
|
}
|
||||||
cats := map[pathType]exchangeCategory{
|
cats := map[pathType]exchangeCategory{
|
||||||
@ -857,6 +877,7 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
|
|||||||
exchangeEventPath: ExchangeEvent,
|
exchangeEventPath: ExchangeEvent,
|
||||||
exchangeMailPath: ExchangeMail,
|
exchangeMailPath: ExchangeMail,
|
||||||
}
|
}
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
scopes input
|
scopes input
|
||||||
@ -880,10 +901,12 @@ func (suite *ExchangeSelectorSuite) TestScopesByCategory() {
|
|||||||
|
|
||||||
func (suite *ExchangeSelectorSuite) TestPasses() {
|
func (suite *ExchangeSelectorSuite) TestPasses() {
|
||||||
deets := details.DetailsEntry{}
|
deets := details.DetailsEntry{}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mid = "mailID"
|
mid = "mailID"
|
||||||
cat = ExchangeMail
|
cat = ExchangeMail
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
es = NewExchangeRestore()
|
es = NewExchangeRestore()
|
||||||
anyUser = setScopesToDefault(es.Users(Any()))
|
anyUser = setScopesToDefault(es.Users(Any()))
|
||||||
@ -934,6 +957,7 @@ func (suite *ExchangeSelectorSuite) TestPasses() {
|
|||||||
|
|
||||||
func (suite *ExchangeSelectorSuite) TestContains() {
|
func (suite *ExchangeSelectorSuite) TestContains() {
|
||||||
target := "fnords"
|
target := "fnords"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
es = NewExchangeRestore()
|
es = NewExchangeRestore()
|
||||||
anyUser = setScopesToDefault(es.Users(Any()))
|
anyUser = setScopesToDefault(es.Users(Any()))
|
||||||
@ -943,6 +967,7 @@ func (suite *ExchangeSelectorSuite) TestContains() {
|
|||||||
wrongType = setScopesToDefault(es.Contacts(Any(), Any(), Any()))
|
wrongType = setScopesToDefault(es.Contacts(Any(), Any(), Any()))
|
||||||
wrongTypeGoodTarget = setScopesToDefault(es.Contacts(Any(), Any(), Any()))
|
wrongTypeGoodTarget = setScopesToDefault(es.Contacts(Any(), Any(), Any()))
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
scopes []ExchangeScope
|
scopes []ExchangeScope
|
||||||
@ -977,6 +1002,7 @@ func (suite *ExchangeSelectorSuite) TestIsAny() {
|
|||||||
specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"mail"}))
|
specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"mail"}))
|
||||||
anyMail = setScopesToDefault(es.Mails(Any(), Any(), Any()))
|
anyMail = setScopesToDefault(es.Mails(Any(), Any(), Any()))
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
scopes []ExchangeScope
|
scopes []ExchangeScope
|
||||||
@ -1041,6 +1067,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathValues() {
|
|||||||
ExchangeMailFolder: mailPath[3],
|
ExchangeMailFolder: mailPath[3],
|
||||||
ExchangeMail: mailPath[4],
|
ExchangeMail: mailPath[4],
|
||||||
}
|
}
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
cat exchangeCategory
|
cat exchangeCategory
|
||||||
path []string
|
path []string
|
||||||
@ -1064,7 +1091,9 @@ func (suite *ExchangeSelectorSuite) TestExchangeCategory_PathKeys() {
|
|||||||
event := []categorizer{ExchangeUser, ExchangeEvent}
|
event := []categorizer{ExchangeUser, ExchangeEvent}
|
||||||
mail := []categorizer{ExchangeUser, ExchangeMailFolder, ExchangeMail}
|
mail := []categorizer{ExchangeUser, ExchangeMailFolder, ExchangeMail}
|
||||||
user := []categorizer{ExchangeUser}
|
user := []categorizer{ExchangeUser}
|
||||||
|
|
||||||
var empty []categorizer
|
var empty []categorizer
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
cat exchangeCategory
|
cat exchangeCategory
|
||||||
expect []categorizer
|
expect []categorizer
|
||||||
|
|||||||
@ -24,6 +24,7 @@ func (mc mockCategorizer) String() string {
|
|||||||
case rootCatStub:
|
case rootCatStub:
|
||||||
return "root"
|
return "root"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ func (ms mockScope) categorizer() categorizer {
|
|||||||
case leafCatStub.String():
|
case leafCatStub.String():
|
||||||
return leafCatStub
|
return leafCatStub
|
||||||
}
|
}
|
||||||
|
|
||||||
return unknownCatStub
|
return unknownCatStub
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +96,7 @@ func stubScope(match string) mockScope {
|
|||||||
if len(match) > 0 {
|
if len(match) > 0 {
|
||||||
sm = match
|
sm = match
|
||||||
}
|
}
|
||||||
|
|
||||||
return mockScope{
|
return mockScope{
|
||||||
rootCatStub.String(): AnyTgt,
|
rootCatStub.String(): AnyTgt,
|
||||||
scopeKeyCategory: rootCatStub.String(),
|
scopeKeyCategory: rootCatStub.String(),
|
||||||
@ -125,5 +128,6 @@ func setScopesToDefault[T scopeT](ts []T) []T {
|
|||||||
for _, s := range ts {
|
for _, s := range ts {
|
||||||
s.setDefaults()
|
s.setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ts
|
return ts
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ func NewOneDriveBackup() *OneDriveBackup {
|
|||||||
newSelector(ServiceOneDrive),
|
newSelector(ServiceOneDrive),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &src
|
return &src
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +40,9 @@ func (s Selector) ToOneDriveBackup() (*OneDriveBackup, error) {
|
|||||||
if s.Service != ServiceOneDrive {
|
if s.Service != ServiceOneDrive {
|
||||||
return nil, badCastErr(ServiceOneDrive, s.Service)
|
return nil, badCastErr(ServiceOneDrive, s.Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
src := OneDriveBackup{oneDrive{s}}
|
src := OneDriveBackup{oneDrive{s}}
|
||||||
|
|
||||||
return &src, nil
|
return &src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,9 +113,11 @@ func (s *oneDrive) Filter(scopes ...[]OneDriveScope) {
|
|||||||
func (s *oneDrive) Users(users []string) []OneDriveScope {
|
func (s *oneDrive) Users(users []string) []OneDriveScope {
|
||||||
users = normalize(users)
|
users = normalize(users)
|
||||||
scopes := []OneDriveScope{}
|
scopes := []OneDriveScope{}
|
||||||
|
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
scopes = append(scopes, makeScope[OneDriveScope](u, Group, OneDriveUser, users))
|
scopes = append(scopes, makeScope[OneDriveScope](u, Group, OneDriveUser, users))
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +202,7 @@ func (c oneDriveCategory) pathValues(path []string) map[categorizer]string {
|
|||||||
if len(path) < 2 {
|
if len(path) < 2 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
m[OneDriveUser] = path[1]
|
m[OneDriveUser] = path[1]
|
||||||
/*
|
/*
|
||||||
TODO/Notice:
|
TODO/Notice:
|
||||||
@ -306,12 +312,15 @@ func (s OneDriveScope) matchesInfo(info *details.OneDriveInfo) bool {
|
|||||||
// the scope must define targets to match on
|
// the scope must define targets to match on
|
||||||
filterCat := s.FilterCategory()
|
filterCat := s.FilterCategory()
|
||||||
targets := s.Get(filterCat)
|
targets := s.Get(filterCat)
|
||||||
|
|
||||||
if len(targets) == 0 {
|
if len(targets) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if targets[0] == AnyTgt {
|
if targets[0] == AnyTgt {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if targets[0] == NoneTgt {
|
if targets[0] == NoneTgt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -323,5 +332,6 @@ func (s OneDriveScope) matchesInfo(info *details.OneDriveInfo) bool {
|
|||||||
return target != NoneTgt
|
return target != NoneTgt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveBackup_DiscreteScopes() {
|
|||||||
expect: Any(),
|
expect: Any(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
eb := NewOneDriveBackup()
|
eb := NewOneDriveBackup()
|
||||||
@ -82,6 +83,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Users() {
|
|||||||
u1 = "u1"
|
u1 = "u1"
|
||||||
u2 = "u2"
|
u2 = "u2"
|
||||||
)
|
)
|
||||||
|
|
||||||
userScopes := sel.Users([]string{u1, u2})
|
userScopes := sel.Users([]string{u1, u2})
|
||||||
for _, scope := range userScopes {
|
for _, scope := range userScopes {
|
||||||
// Scope value is either u1 or u2
|
// Scope value is either u1 or u2
|
||||||
|
|||||||
@ -128,6 +128,7 @@ func makeScope[T scopeT](
|
|||||||
cat.String(): join(vs...),
|
cat.String(): join(vs...),
|
||||||
cat.rootCat().String(): resource,
|
cat.rootCat().String(): resource,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,19 +158,24 @@ func contains[T scopeT, C categoryT](s T, cat C, target string) bool {
|
|||||||
if !typeAndCategoryMatches(cat, s.categorizer()) {
|
if !typeAndCategoryMatches(cat, s.categorizer()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(target) == 0 {
|
if len(target) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
compare := s[cat.String()]
|
compare := s[cat.String()]
|
||||||
if len(compare) == 0 {
|
if len(compare) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if compare == NoneTgt {
|
if compare == NoneTgt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if compare == AnyTgt {
|
if compare == AnyTgt {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Contains(compare, target)
|
return strings.Contains(compare, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +187,7 @@ func getCatValue[T scopeT](s T, cat categorizer) []string {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return None()
|
return None()
|
||||||
}
|
}
|
||||||
|
|
||||||
return split(v)
|
return split(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +210,7 @@ func isAnyTarget[T scopeT, C categoryT](s T, cat C) bool {
|
|||||||
if !typeAndCategoryMatches(cat, s.categorizer()) {
|
if !typeAndCategoryMatches(cat, s.categorizer()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return s[cat.String()] == AnyTgt
|
return s[cat.String()] == AnyTgt
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +237,7 @@ func reduce[T scopeT, C categoryT](
|
|||||||
for _, ent := range deets.Entries {
|
for _, ent := range deets.Entries {
|
||||||
// todo: use Path pkg for this
|
// todo: use Path pkg for this
|
||||||
path := strings.Split(ent.RepoRef, "/")
|
path := strings.Split(ent.RepoRef, "/")
|
||||||
|
|
||||||
dc, ok := dataCategories[pathTypeIn(path)]
|
dc, ok := dataCategories[pathTypeIn(path)]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
@ -249,6 +258,7 @@ func reduce[T scopeT, C categoryT](
|
|||||||
|
|
||||||
reduced := &details.Details{DetailsModel: deets.DetailsModel}
|
reduced := &details.Details{DetailsModel: deets.DetailsModel}
|
||||||
reduced.Entries = ents
|
reduced.Entries = ents
|
||||||
|
|
||||||
return reduced
|
return reduced
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +285,7 @@ func pathTypeIn(path []string) pathType {
|
|||||||
if len(path) < 3 {
|
if len(path) < 3 {
|
||||||
return unknownPathType
|
return unknownPathType
|
||||||
}
|
}
|
||||||
|
|
||||||
switch path[2] {
|
switch path[2] {
|
||||||
case "mail":
|
case "mail":
|
||||||
return exchangeMailPath
|
return exchangeMailPath
|
||||||
@ -283,6 +294,7 @@ func pathTypeIn(path []string) pathType {
|
|||||||
case "event":
|
case "event":
|
||||||
return exchangeEventPath
|
return exchangeEventPath
|
||||||
}
|
}
|
||||||
|
|
||||||
return unknownPathType
|
return unknownPathType
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +319,7 @@ func scopesByCategory[T scopeT, C categoryT](
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,12 +341,14 @@ func passes[T scopeT](
|
|||||||
if len(incs) > 0 {
|
if len(incs) > 0 {
|
||||||
// at least one inclusion must apply.
|
// at least one inclusion must apply.
|
||||||
var included bool
|
var included bool
|
||||||
|
|
||||||
for _, inc := range incs {
|
for _, inc := range incs {
|
||||||
if inc.matchesEntry(cat, pathValues, entry) {
|
if inc.matchesEntry(cat, pathValues, entry) {
|
||||||
included = true
|
included = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !included {
|
if !included {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -389,6 +404,7 @@ func matchesPathValues[T scopeT, C categoryT](
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,5 +438,6 @@ func typeAndCategoryMatches[C categoryT](a C, b categorizer) bool {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return categoryMatches(a, bb)
|
return categoryMatches(a, bb)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -226,6 +226,7 @@ func (suite *SelectorScopesSuite) TestReduce() {
|
|||||||
dataCats := map[pathType]mockCategorizer{
|
dataCats := map[pathType]mockCategorizer{
|
||||||
unknownPathType: rootCatStub,
|
unknownPathType: rootCatStub,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range reduceTestTable {
|
for _, test := range reduceTestTable {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
ds := deets()
|
ds := deets()
|
||||||
@ -264,6 +265,7 @@ func (suite *SelectorScopesSuite) TestPasses() {
|
|||||||
cat := rootCatStub
|
cat := rootCatStub
|
||||||
pathVals := map[categorizer]string{}
|
pathVals := map[categorizer]string{}
|
||||||
entry := details.DetailsEntry{}
|
entry := details.DetailsEntry{}
|
||||||
|
|
||||||
for _, test := range reduceTestTable {
|
for _, test := range reduceTestTable {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
sel := test.sel()
|
sel := test.sel()
|
||||||
@ -284,10 +286,13 @@ func toMockScope(sc []scope) []mockScope {
|
|||||||
if len(sc) == 0 {
|
if len(sc) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ms := []mockScope{}
|
ms := []mockScope{}
|
||||||
|
|
||||||
for _, s := range sc {
|
for _, s := range sc {
|
||||||
ms = append(ms, mockScope(s))
|
ms = append(ms, mockScope(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -103,6 +103,7 @@ func (s Selector) String() string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "error"
|
return "error"
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(bs)
|
return string(bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,12 +114,14 @@ func appendScopes[T scopeT](to []scope, scopes ...[]T) []scope {
|
|||||||
if len(to) == 0 {
|
if len(to) == 0 {
|
||||||
to = []scope{}
|
to = []scope{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, scopeSl := range scopes {
|
for _, scopeSl := range scopes {
|
||||||
for _, s := range scopeSl {
|
for _, s := range scopeSl {
|
||||||
s.setDefaults()
|
s.setDefaults()
|
||||||
to = append(to, scope(s))
|
to = append(to, scope(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +129,11 @@ func appendScopes[T scopeT](to []scope, scopes ...[]T) []scope {
|
|||||||
// future TODO: if Inclues is nil, return filters.
|
// future TODO: if Inclues is nil, return filters.
|
||||||
func scopes[T scopeT](s Selector) []T {
|
func scopes[T scopeT](s Selector) []T {
|
||||||
scopes := []T{}
|
scopes := []T{}
|
||||||
|
|
||||||
for _, v := range s.Includes {
|
for _, v := range s.Includes {
|
||||||
scopes = append(scopes, T(v))
|
scopes = append(scopes, T(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,10 +163,11 @@ func discreteScopes[T scopeT, C categoryT](
|
|||||||
for k, v := range t {
|
for k, v := range t {
|
||||||
w[k] = v
|
w[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
set(w, rootCat, jdid)
|
set(w, rootCat, jdid)
|
||||||
t = w
|
t = w
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sl = append(sl, t)
|
sl = append(sl, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,9 +209,11 @@ func (p Printable) Resources() string {
|
|||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
s = resourcesShortFormat(p.Filters)
|
s = resourcesShortFormat(p.Filters)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
s = "All"
|
s = "All"
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,13 +221,16 @@ func (p Printable) Resources() string {
|
|||||||
// plus, if more exist, " (len-1 more)"
|
// plus, if more exist, " (len-1 more)"
|
||||||
func resourcesShortFormat(m map[string][]string) string {
|
func resourcesShortFormat(m map[string][]string) string {
|
||||||
var s string
|
var s string
|
||||||
|
|
||||||
for k := range m {
|
for k := range m {
|
||||||
s = k
|
s = k
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s) > 0 && len(m) > 1 {
|
if len(s) > 0 && len(m) > 1 {
|
||||||
s = fmt.Sprintf("%s (%d more)", s, len(m)-1)
|
s = fmt.Sprintf("%s (%d more)", s, len(m)-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,14 +241,18 @@ func toResourceTypeMap(ms []scope) map[string][]string {
|
|||||||
if len(ms) == 0 {
|
if len(ms) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
r := make(map[string][]string)
|
r := make(map[string][]string)
|
||||||
|
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
res := m[scopeKeyResource]
|
res := m[scopeKeyResource]
|
||||||
if res == AnyTgt {
|
if res == AnyTgt {
|
||||||
res = All
|
res = All
|
||||||
}
|
}
|
||||||
|
|
||||||
r[res] = addToSet(r[res], m[scopeKeyDataType])
|
r[res] = addToSet(r[res], m[scopeKeyDataType])
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,11 +263,13 @@ func addToSet(set []string, v string) []string {
|
|||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
return []string{v}
|
return []string{v}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range set {
|
for _, s := range set {
|
||||||
if s == v {
|
if s == v {
|
||||||
return set
|
return set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(set, v)
|
return append(set, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,13 +310,16 @@ func normalize(s []string) []string {
|
|||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return None()
|
return None()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range s {
|
for _, e := range s {
|
||||||
if e == AnyTgt {
|
if e == AnyTgt {
|
||||||
return Any()
|
return Any()
|
||||||
}
|
}
|
||||||
|
|
||||||
if e == NoneTgt {
|
if e == NoneTgt {
|
||||||
return None()
|
return None()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,7 @@ func (suite *SelectorSuite) TestContains() {
|
|||||||
does[key.String()] = target
|
does[key.String()] = target
|
||||||
doesNot := stubScope("")
|
doesNot := stubScope("")
|
||||||
doesNot[key.String()] = "smarf"
|
doesNot[key.String()] = "smarf"
|
||||||
|
|
||||||
assert.True(t, contains(does, key, target), "does contain")
|
assert.True(t, contains(does, key, target), "does contain")
|
||||||
assert.False(t, contains(doesNot, key, target), "does not contain")
|
assert.False(t, contains(doesNot, key, target), "does not contain")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,16 +26,19 @@ func (c CommonConfig) StringConfig() (map[string]string, error) {
|
|||||||
keyCommonCorsoPassword: c.CorsoPassword,
|
keyCommonCorsoPassword: c.CorsoPassword,
|
||||||
keyCommonKopiaCfgDir: c.KopiaCfgDir,
|
keyCommonKopiaCfgDir: c.KopiaCfgDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, c.validate()
|
return cfg, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommonConfig retrieves the CommonConfig details from the Storage config.
|
// CommonConfig retrieves the CommonConfig details from the Storage config.
|
||||||
func (s Storage) CommonConfig() (CommonConfig, error) {
|
func (s Storage) CommonConfig() (CommonConfig, error) {
|
||||||
c := CommonConfig{}
|
c := CommonConfig{}
|
||||||
|
|
||||||
if len(s.Config) > 0 {
|
if len(s.Config) > 0 {
|
||||||
c.CorsoPassword = orEmptyString(s.Config[keyCommonCorsoPassword])
|
c.CorsoPassword = orEmptyString(s.Config[keyCommonCorsoPassword])
|
||||||
c.KopiaCfgDir = orEmptyString(s.Config[keyCommonKopiaCfgDir])
|
c.KopiaCfgDir = orEmptyString(s.Config[keyCommonKopiaCfgDir])
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, c.validate()
|
return c, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +47,7 @@ func (c CommonConfig) validate() error {
|
|||||||
if len(c.CorsoPassword) == 0 {
|
if len(c.CorsoPassword) == 0 {
|
||||||
return errors.Wrap(errMissingRequired, credentials.CorsoPassword)
|
return errors.Wrap(errMissingRequired, credentials.CorsoPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kopiaCfgFilePath is not required
|
// kopiaCfgFilePath is not required
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,12 +43,14 @@ func (c S3Config) StringConfig() (map[string]string, error) {
|
|||||||
keyS3SecretKey: c.SecretKey,
|
keyS3SecretKey: c.SecretKey,
|
||||||
keyS3SessionToken: c.SessionToken,
|
keyS3SessionToken: c.SessionToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg, c.validate()
|
return cfg, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// S3Config retrieves the S3Config details from the Storage config.
|
// S3Config retrieves the S3Config details from the Storage config.
|
||||||
func (s Storage) S3Config() (S3Config, error) {
|
func (s Storage) S3Config() (S3Config, error) {
|
||||||
c := S3Config{}
|
c := S3Config{}
|
||||||
|
|
||||||
if len(s.Config) > 0 {
|
if len(s.Config) > 0 {
|
||||||
c.AccessKey = orEmptyString(s.Config[keyS3AccessKey])
|
c.AccessKey = orEmptyString(s.Config[keyS3AccessKey])
|
||||||
c.Bucket = orEmptyString(s.Config[keyS3Bucket])
|
c.Bucket = orEmptyString(s.Config[keyS3Bucket])
|
||||||
@ -57,6 +59,7 @@ func (s Storage) S3Config() (S3Config, error) {
|
|||||||
c.SecretKey = orEmptyString(s.Config[keyS3SecretKey])
|
c.SecretKey = orEmptyString(s.Config[keyS3SecretKey])
|
||||||
c.SessionToken = orEmptyString(s.Config[keyS3SessionToken])
|
c.SessionToken = orEmptyString(s.Config[keyS3SessionToken])
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, c.validate()
|
return c, c.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,5 +75,6 @@ func (c S3Config) validate() error {
|
|||||||
return errors.Wrap(errMissingRequired, k)
|
return errors.Wrap(errMissingRequired, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ type Storage struct {
|
|||||||
// NewStorage aggregates all the supplied configurations into a single configuration.
|
// NewStorage aggregates all the supplied configurations into a single configuration.
|
||||||
func NewStorage(p storageProvider, cfgs ...common.StringConfigurer) (Storage, error) {
|
func NewStorage(p storageProvider, cfgs ...common.StringConfigurer) (Storage, error) {
|
||||||
cs, err := common.UnionStringConfigs(cfgs...)
|
cs, err := common.UnionStringConfigs(cfgs...)
|
||||||
|
|
||||||
return Storage{
|
return Storage{
|
||||||
Provider: p,
|
Provider: p,
|
||||||
Config: cs,
|
Config: cs,
|
||||||
@ -53,8 +54,10 @@ func orEmptyString(v any) string {
|
|||||||
fmt.Printf("panic recovery casting %v to string\n", v)
|
fmt.Printf("panic recovery casting %v to string\n", v)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.(string)
|
return v.(string)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,10 +14,12 @@ import (
|
|||||||
// GetBackup gets a single backup by id.
|
// GetBackup gets a single backup by id.
|
||||||
func (w Wrapper) GetBackup(ctx context.Context, backupID model.StableID) (*backup.Backup, error) {
|
func (w Wrapper) GetBackup(ctx context.Context, backupID model.StableID) (*backup.Backup, error) {
|
||||||
b := backup.Backup{}
|
b := backup.Backup{}
|
||||||
|
|
||||||
err := w.Get(ctx, model.BackupSchema, backupID, &b)
|
err := w.Get(ctx, model.BackupSchema, backupID, &b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "getting backup")
|
return nil, errors.Wrap(err, "getting backup")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &b, nil
|
return &b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,15 +29,20 @@ func (w Wrapper) GetBackups(ctx context.Context) ([]backup.Backup, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := make([]backup.Backup, len(bms))
|
bs := make([]backup.Backup, len(bms))
|
||||||
|
|
||||||
for i, bm := range bms {
|
for i, bm := range bms {
|
||||||
b := backup.Backup{}
|
b := backup.Backup{}
|
||||||
|
|
||||||
err := w.GetWithModelStoreID(ctx, model.BackupSchema, bm.ModelStoreID, &b)
|
err := w.GetWithModelStoreID(ctx, model.BackupSchema, bm.ModelStoreID, &b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bs[i] = b
|
bs[i] = b
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs, nil
|
return bs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,19 +52,23 @@ func (w Wrapper) DeleteBackup(ctx context.Context, backupID model.StableID) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.Delete(ctx, model.BackupDetailsSchema, deets.ID); err != nil {
|
if err := w.Delete(ctx, model.BackupDetailsSchema, deets.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return w.Delete(ctx, model.BackupSchema, backupID)
|
return w.Delete(ctx, model.BackupSchema, backupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDetails gets the backup details by ID.
|
// GetDetails gets the backup details by ID.
|
||||||
func (w Wrapper) GetDetails(ctx context.Context, detailsID manifest.ID) (*details.Details, error) {
|
func (w Wrapper) GetDetails(ctx context.Context, detailsID manifest.ID) (*details.Details, error) {
|
||||||
d := details.Details{}
|
d := details.Details{}
|
||||||
|
|
||||||
err := w.GetWithModelStoreID(ctx, model.BackupDetailsSchema, detailsID, &d)
|
err := w.GetWithModelStoreID(ctx, model.BackupDetailsSchema, detailsID, &d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "getting details")
|
return nil, errors.Wrap(err, "getting details")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &d, nil
|
return &d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,7 @@ func (mms *MockModelStore) Get(
|
|||||||
if mms.err != nil {
|
if mms.err != nil {
|
||||||
return mms.err
|
return mms.err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case model.BackupSchema:
|
case model.BackupSchema:
|
||||||
unmarshal(mms.backup, data)
|
unmarshal(mms.backup, data)
|
||||||
@ -73,6 +74,7 @@ func (mms *MockModelStore) Get(
|
|||||||
default:
|
default:
|
||||||
return errors.Errorf("schema %s not supported by mock Get", s)
|
return errors.Errorf("schema %s not supported by mock Get", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,16 +86,20 @@ func (mms *MockModelStore) GetIDsForType(
|
|||||||
if mms.err != nil {
|
if mms.err != nil {
|
||||||
return nil, mms.err
|
return nil, mms.err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case model.BackupSchema:
|
case model.BackupSchema:
|
||||||
b := backup.Backup{}
|
b := backup.Backup{}
|
||||||
unmarshal(mms.backup, &b)
|
unmarshal(mms.backup, &b)
|
||||||
|
|
||||||
return []*model.BaseModel{&b.BaseModel}, nil
|
return []*model.BaseModel{&b.BaseModel}, nil
|
||||||
case model.BackupDetailsSchema:
|
case model.BackupDetailsSchema:
|
||||||
d := details.Details{}
|
d := details.Details{}
|
||||||
unmarshal(mms.backup, &d)
|
unmarshal(mms.backup, &d)
|
||||||
|
|
||||||
return []*model.BaseModel{&d.BaseModel}, nil
|
return []*model.BaseModel{&d.BaseModel}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.Errorf("schema %s not supported by mock GetIDsForType", s)
|
return nil, errors.Errorf("schema %s not supported by mock GetIDsForType", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +112,7 @@ func (mms *MockModelStore) GetWithModelStoreID(
|
|||||||
if mms.err != nil {
|
if mms.err != nil {
|
||||||
return mms.err
|
return mms.err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case model.BackupSchema:
|
case model.BackupSchema:
|
||||||
unmarshal(mms.backup, data)
|
unmarshal(mms.backup, data)
|
||||||
@ -114,6 +121,7 @@ func (mms *MockModelStore) GetWithModelStoreID(
|
|||||||
default:
|
default:
|
||||||
return errors.Errorf("schema %s not supported by mock GetWithModelStoreID", s)
|
return errors.Errorf("schema %s not supported by mock GetWithModelStoreID", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +138,7 @@ func (mms *MockModelStore) Put(ctx context.Context, s model.Schema, m model.Mode
|
|||||||
default:
|
default:
|
||||||
return errors.Errorf("schema %s not supported by mock Put", s)
|
return errors.Errorf("schema %s not supported by mock Put", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mms.err
|
return mms.err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,5 +151,6 @@ func (mms *MockModelStore) Update(ctx context.Context, s model.Schema, m model.M
|
|||||||
default:
|
default:
|
||||||
return errors.Errorf("schema %s not supported by mock Update", s)
|
return errors.Errorf("schema %s not supported by mock Update", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mms.err
|
return mms.err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user