add bool format checks for string flags (#1072)

* add bool format checks for string flags

Adds a boolean-parseable validator for cli flags
that accept strings representing boolean values.

* fix ctx production in cli integration test
This commit is contained in:
Keepers 2022-10-12 18:02:22 -06:00 committed by GitHub
parent 41319c117f
commit e26a1a7b31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 28 deletions

View File

@ -376,12 +376,11 @@ func exchangeDetailsCmd() *cobra.Command {
// lists the history of backup operations
func detailsExchangeCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if utils.HasNoFlagsAndShownHelp(cmd) {
return nil
}
ctx := cmd.Context()
opts := utils.ExchangeOpts{
Contacts: contact,
ContactFolders: contactFolder,
@ -402,10 +401,6 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error {
EventSubject: eventSubject,
}
if err := utils.ValidateExchangeRestoreFlags(backupID, opts); err != nil {
return err
}
s, acct, err := config.GetStorageAndAccount(ctx, true, nil)
if err != nil {
return Only(ctx, err)
@ -441,6 +436,10 @@ func runDetailsExchangeCmd(
backupID string,
opts utils.ExchangeOpts,
) (*details.Details, error) {
if err := utils.ValidateExchangeRestoreFlags(backupID, opts); err != nil {
return nil, err
}
d, _, err := r.BackupDetails(ctx, backupID)
if err != nil {
if errors.Is(err, kopia.ErrNotFound) {

View File

@ -250,22 +250,21 @@ func (suite *ExchangeSuite) TestExchangeBackupDetailsSelectorsBadBackupID() {
assert.Empty(t, output)
}
// TODO(ashmrtn): Uncomment these when the CLI validates flag input values.
//func (suite *ExchangeSuite) TestExchangeBackupDetailsSelectorsBadFormats() {
// ctx, flush := tester.NewContext()
// defer flush()
//
// for _, test := range testdata.BadExchangeOptionsFormats {
// suite.T().Run(test.Name, func(t *testing.T) {
// output, err := runDetailsExchangeCmd(
// ctx,
// test.BackupGetter,
// "backup-ID",
// test.Opts,
// )
// assert.Error(t, err)
//
// assert.Empty(t, output)
// })
// }
//}
func (suite *ExchangeSuite) TestExchangeBackupDetailsSelectorsBadFormats() {
ctx, flush := tester.NewContext()
defer flush()
for _, test := range testdata.BadExchangeOptionsFormats {
suite.T().Run(test.Name, func(t *testing.T) {
output, err := runDetailsExchangeCmd(
ctx,
test.BackupGetter,
"backup-ID",
test.Opts,
)
assert.Error(t, err)
assert.Empty(t, output)
})
}
}

View File

@ -1,6 +1,7 @@
package restore_test
import (
"context"
"testing"
"github.com/spf13/viper"
@ -176,3 +177,33 @@ func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd_badTimeFlag
})
}
}
func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd_badBoolFlags() {
for _, set := range backupDataSets {
if set != events {
suite.T().Skip()
}
suite.T().Run(set.String(), func(t *testing.T) {
ctx := config.SetViper(context.Background(), suite.vpr)
ctx, flush := tester.WithContext(ctx)
defer flush()
var timeFilter string
switch set {
case events:
timeFilter = "--event-recurs"
}
cmd := tester.StubRootCmd(
"restore", "exchange",
"--config-file", suite.cfgFP,
"--backup", string(suite.backupOps[set].Results.BackupID),
timeFilter, "wingbat")
cli.BuildCommandTree(cmd)
// run the command
require.Error(t, cmd.ExecuteContext(ctx))
})
}
}

View File

@ -93,6 +93,10 @@ func ValidateExchangeRestoreFlags(backupID string, opts ExchangeOpts) error {
return errors.New("invalid time format for event-starts-before")
}
if !IsValidBool(opts.EventRecurs) {
return errors.New("invalid format for event-recurs")
}
return nil
}

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strconv"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@ -69,9 +70,19 @@ func IsValidTimeFormat(in string) bool {
}
_, err := common.ParseTime(in)
if err != nil {
return false
return err == nil
}
// IsValidTimeFormat returns true if the input is regonized as a
// boolean. Returns true if the input is zero valued, which
// indicates that the flag was not called.
func IsValidBool(in string) bool {
if len(in) == 0 {
return true
}
return true
_, err := strconv.ParseBool(in)
return err == nil
}