diff --git a/config/versions/v4.go b/config/versions/v4.go index 21c506d5f75..ff52dad9a1a 100644 --- a/config/versions/v4.go +++ b/config/versions/v4.go @@ -26,8 +26,8 @@ var defaultConfig = []byte(`{ "verbose": false, "activelyTrackFuturesPositions": true, "futuresTrackingSeekDuration": ` + defaultFuturesTrackingSeekDuration + `, - "respectOrderHistoryLimits": true, - "cancelOrdersOnShutdown": false + "cancelOrdersOnShutdown": false, + "respectOrderHistoryLimits": true }`) // UpgradeConfig handles upgrading config for OrderManager: @@ -62,7 +62,12 @@ func (v *Version4) UpgradeConfig(_ context.Context, e []byte) ([]byte, error) { return e, nil } -// DowngradeConfig doesn't need to do anything for this version, since it's a lossy downgrade +// DowngradeConfig just reverses the futuresTrackingSeekDuration to negative, and leaves everything else alone func (v *Version4) DowngradeConfig(_ context.Context, e []byte) ([]byte, error) { + if i, err := jsonparser.GetInt(e, "orderManager", "futuresTrackingSeekDuration"); err == nil && i > 0 { + if e, err = jsonparser.Set(e, []byte(strconv.Itoa(0-int(i))), "orderManager", "futuresTrackingSeekDuration"); err != nil { + return e, err + } + } return e, nil } diff --git a/config/versions/v4_test.go b/config/versions/v4_test.go index d8809eefb0e..c2e049c587f 100644 --- a/config/versions/v4_test.go +++ b/config/versions/v4_test.go @@ -7,49 +7,62 @@ import ( "strings" "testing" + "github.com/buger/jsonparser" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var ( + rOHLT = `"respectOrderHistoryLimits":true,` + rOHLN = `"respectOrderHistoryLimits":null,` + expDef = `{"orderManager":{"enabled":true,"verbose":false,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":31536000000000000,"cancelOrdersOnShutdown":false,"respectOrderHistoryLimits":true}}` + expUser1 = `{"orderManager":{"enabled":false,"verbose":true,"activelyTrackFuturesPositions":false,"futuresTrackingSeekDuration":47000,"cancelOrdersOnShutdown":true,"respectOrderHistoryLimits":true}}` +) + +var tests = []struct { + name string + in string + out string + err error +}{ + {name: "Bad input should error", err: jsonparser.KeyPathNotFoundError}, + {name: "Missing orderManager should use the defaults", in: "{}", out: expDef}, + {name: "Enabled null should use defaults", in: strings.Replace(expDef, "true", "null", 1), out: expDef}, + {name: "RespectOrderHistoryLimits should be added if missing", in: strings.Replace(expUser1, `"respectOrderHistoryLimits":true,`, "", 1), out: expUser1}, + {name: "RespectOrderHistoryLimits null should default true", in: strings.Replace(expUser1, `mits":true`, `mits":null`, 1), out: expUser1}, + {name: "RespectOrderHistoryLimits null should default true", in: strings.Replace(expUser1, `mits":false`, `mits":false`, 1), out: expUser1}, + {name: "FutureTracking should be reversed", in: strings.Replace(expUser1, "47", "-47", 1), out: expUser1}, + {name: "Configured orderManager should be left alone", in: expUser1, out: expUser1}, +} + func TestVersion4Upgrade(t *testing.T) { t.Parallel() - out, err := new(Version4).UpgradeConfig(context.Background(), []byte(`{}`)) - require.NoError(t, err) b := new(bytes.Buffer) - require.NoError(t, json.Compact(b, out), "json.Compact must not error") - def := `{"orderManager":{"enabled":true,"verbose":false,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":31536000000000000,"respectOrderHistoryLimits":true,"cancelOrdersOnShutdown":false}}` - require.Equal(t, def, b.String()) - - in := []byte(`{"orderManager":{"enabled":false,"verbose":true,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":3600000,"cancelOrdersOnShutdown":false}}`) - out, err = new(Version4).UpgradeConfig(context.Background(), in) - require.NoError(t, err) - exp := `{"orderManager":{"enabled":false,"verbose":true,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":3600000,"cancelOrdersOnShutdown":false,"respectOrderHistoryLimits":true}}` - require.Equal(t, exp, string(out)) - - in = []byte(`{"orderManager":{"enabled":null,"verbose":false,"activelyTrackFuturesPositions":false,"futuresTrackingSeekDuration":0,"cancelOrdersOnShutdown":false,"respectOrderHistoryLimits":null}}`) - out, err = new(Version4).UpgradeConfig(context.Background(), in) - require.NoError(t, err) - b.Reset() - require.NoError(t, json.Compact(b, out), "json.Compact must not error") - require.Equal(t, def, b.String()) - - in = []byte(`{"orderManager":{"enabled":true,"verbose":true,"activelyTrackFuturesPositions":false,"futuresTrackingSeekDuration":0,"cancelOrdersOnShutdown":true,"respectOrderHistoryLimits":null}}`) - out, err = new(Version4).UpgradeConfig(context.Background(), in) - require.NoError(t, err) - b.Reset() - require.NoError(t, json.Compact(b, out), "json.Compact must not error") - require.Equal(t, strings.Replace(string(in), "null", "true", 1), b.String()) - - t.Error("Tests for reversing the amount") + for _, tt := range tests { + _ = t.Run(tt.name, func(t *testing.T) { + out, err := new(Version4).UpgradeConfig(context.Background(), []byte(tt.in)) + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + b.Reset() + require.NoError(t, json.Compact(b, out), "json.Compact must not error") + require.Equal(t, tt.out, b.String()) + }) + } } func TestVersion4Downgrade(t *testing.T) { t.Parallel() - in := []byte(`{"orderManager":{"enabled":false,"verbose":true}}`) - out, err := new(Version4).DowngradeConfig(context.Background(), in) + + expReversed := strings.Replace(expUser1, "47", "-47", 1) + out, err := new(Version4).DowngradeConfig(context.Background(), []byte(expUser1)) require.NoError(t, err) - assert.Equal(t, string(in), string(out), "Downgrade should not touch the config") + assert.Equal(t, expReversed, string(out), "Downgrade should just reverse the futuresTrackingSeekDuration") - t.Error("Not so fast. Reverse the number back") + out, err = new(Version4).DowngradeConfig(context.Background(), []byte(expUser1)) + require.NoError(t, err) + assert.Equal(t, expReversed, expReversed, "Downgrade should leave an already negative futuresTrackingSeekDuration alone") }