diff --git a/server/start.go b/server/start.go index 5a9cd0500..7d7b40e46 100644 --- a/server/start.go +++ b/server/start.go @@ -20,18 +20,23 @@ import ( // Tendermint full-node start flags const ( - flagWithTendermint = "with-tendermint" - flagAddress = "address" - flagTraceStore = "trace-store" - flagPruning = "pruning" - flagCPUProfile = "cpu-profile" - FlagMinGasPrices = "minimum-gas-prices" - FlagHaltHeight = "halt-height" - FlagHaltTime = "halt-time" - FlagInterBlockCache = "inter-block-cache" - FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" + flagWithTendermint = "with-tendermint" + flagAddress = "address" + flagTraceStore = "trace-store" + flagPruning = "pruning" + flagPruningKeepEvery = "pruning-keep-every" + flagPruningSnapshotEvery = "pruning-snapshot-every" + flagCPUProfile = "cpu-profile" + FlagMinGasPrices = "minimum-gas-prices" + FlagHaltHeight = "halt-height" + FlagHaltTime = "halt-time" + FlagInterBlockCache = "inter-block-cache" + FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" ) +var errPruningWithGranularOptions = fmt.Errorf("%s flag is not compatible with granular options as %s or %s", flagPruning, flagPruningKeepEvery, flagPruningSnapshotEvery) +var errPruningGranularOptions = fmt.Errorf("%s and %s must be set together", flagPruningSnapshotEvery, flagPruningKeepEvery) + // StartCmd runs the service passed in, either stand-alone or in-process with // Tendermint. func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { @@ -56,6 +61,21 @@ will not be able to commit subsequent blocks. For profiling and benchmarking purposes, CPU profiling can be enabled via the '--cpu-profile' flag which accepts a path for the resulting pprof file. `, + PreRunE: func(cmd *cobra.Command, args []string) error { + if viper.IsSet(flagPruning) { + if viper.IsSet(flagPruningKeepEvery) || viper.IsSet(flagPruningSnapshotEvery) { + return errPruningWithGranularOptions + } + + return nil + } + + if !(viper.IsSet(flagPruningKeepEvery) && viper.IsSet(flagPruningSnapshotEvery)) { + return errPruningGranularOptions + } + + return nil + }, RunE: func(cmd *cobra.Command, args []string) error { if !viper.GetBool(flagWithTendermint) { ctx.Logger.Info("starting ABCI without Tendermint") diff --git a/server/start_test.go b/server/start_test.go new file mode 100644 index 000000000..cd7c6b6ae --- /dev/null +++ b/server/start_test.go @@ -0,0 +1,94 @@ +package server + +import ( + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/require" +) + +func TestPruningOptions(t *testing.T) { + startCommand := StartCmd(nil, nil) + + tests := []struct { + name string + paramInit func() + returnsErr bool + expectedErr error + }{ + { + name: "only keep-every provided", + paramInit: func() { + viper.Set(flagPruningKeepEvery, 12345) + }, + returnsErr: true, + expectedErr: errPruningGranularOptions, + }, + { + name: "only snapshot-every provided", + paramInit: func() { + viper.Set(flagPruningSnapshotEvery, 12345) + }, + returnsErr: true, + expectedErr: errPruningGranularOptions, + }, + { + name: "pruning flag with other granular options 1", + paramInit: func() { + viper.Set(flagPruning, "set") + viper.Set(flagPruningSnapshotEvery, 1234) + }, + returnsErr: true, + expectedErr: errPruningWithGranularOptions, + }, + { + name: "pruning flag with other granular options 2", + paramInit: func() { + viper.Set(flagPruning, "set") + viper.Set(flagPruningKeepEvery, 1234) + }, + returnsErr: true, + expectedErr: errPruningWithGranularOptions, + }, + { + name: "pruning flag with other granular options 3", + paramInit: func() { + viper.Set(flagPruning, "set") + viper.Set(flagPruningKeepEvery, 1234) + viper.Set(flagPruningSnapshotEvery, 1234) + }, + returnsErr: true, + expectedErr: errPruningWithGranularOptions, + }, + { + name: "only prunning set", + paramInit: func() { + viper.Set(flagPruning, "set") + }, + returnsErr: false, + expectedErr: nil, + }, + { + name: "only granular set", + paramInit: func() { + viper.Set(flagPruningSnapshotEvery, 12345) + viper.Set(flagPruningKeepEvery, 12345) + }, + returnsErr: false, + expectedErr: nil, + }, + } + + for _, tt := range tests { + viper.Reset() + tt.paramInit() + + err := startCommand.PreRunE(nil, nil) + + if tt.returnsErr { + require.EqualError(t, err, tt.expectedErr.Error()) + } else { + require.NoError(t, err) + } + } +}