fs: make BwTimetable.Set replace the timetable instead of appending to it
Set built the timetable with *x = append(*x, ts), so setting a bandwidth
timetable on a value that already held one kept both schedules. The single-value
branch of the same function has always done *x = BwTimetable{ts}, and the other
multi-token Set methods in this package build into a local and assign at the end.
The visible effect is through the rc API. The "main" options block registered in
fs.RegisterGlobalOptions is the live globalConfig, and options/set reshapes JSON
straight into it, so
rclone rc options/set --json '{"main": {"BwLimit": "Mon-10:00,1Mi"}}'
added to the running daemon's timetable rather than replacing it, and the older
slot kept winning: LimitAt for a Sunday returned the previous 10Mi. The same
applies to a _config override on a single call, since AddConfig shallow-copies
the global.
Building into a local also stops a failed parse from leaving the previous
timetable partly overwritten, which the existing error cases already expect.
This commit is contained in:
committed by
Nick Craig-Wood
parent
e45210765c
commit
5bbc5d5545
+5
-2
@@ -150,6 +150,8 @@ func (x *BwTimetable) Set(s string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newTimetable BwTimetable
|
||||||
|
|
||||||
// Split the timetable string by both spaces and semicolons
|
// Split the timetable string by both spaces and semicolons
|
||||||
for tok := range strings.FieldsFuncSeq(s, func(r rune) bool {
|
for tok := range strings.FieldsFuncSeq(s, func(r rune) bool {
|
||||||
return r == ' ' || r == ';'
|
return r == ' ' || r == ';'
|
||||||
@@ -178,7 +180,7 @@ func (x *BwTimetable) Set(s string) error {
|
|||||||
if err := ts.Bandwidth.Set(tv[1]); err != nil {
|
if err := ts.Bandwidth.Set(tv[1]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*x = append(*x, ts)
|
newTimetable = append(newTimetable, ts)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
timespec := strings.Split(tv[0], "-")
|
timespec := strings.Split(tv[0], "-")
|
||||||
@@ -205,9 +207,10 @@ func (x *BwTimetable) Set(s string) error {
|
|||||||
if err := ts.Bandwidth.Set(tv[1]); err != nil {
|
if err := ts.Bandwidth.Set(tv[1]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*x = append(*x, ts)
|
newTimetable = append(newTimetable, ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*x = newTimetable
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,52 @@ func TestBwTimetableSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBwTimetableSetReplaces(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
first string
|
||||||
|
second string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"Sun-00:00,10M", "Mon-10:00,1M", "Mon-10:00,1Mi"},
|
||||||
|
{"Mon-10:00,1M", "Mon-10:00,1M", "Mon-10:00,1Mi"},
|
||||||
|
{"Mon-10:00,1M", "2M", "2Mi"},
|
||||||
|
{"2M", "Mon-10:00,1M", "Mon-10:00,1Mi"},
|
||||||
|
{"11:00,333;13:40,666", "Mon-10:00,1M", "Mon-10:00,1Mi"},
|
||||||
|
} {
|
||||||
|
tt := BwTimetable{}
|
||||||
|
require.NoError(t, tt.Set(test.first), test.first)
|
||||||
|
require.NoError(t, tt.Set(test.second), test.second)
|
||||||
|
assert.Equal(t, test.want, tt.String(), "%q then %q", test.first, test.second)
|
||||||
|
|
||||||
|
var want BwTimetable
|
||||||
|
require.NoError(t, want.Set(test.second))
|
||||||
|
assert.Equal(t, want, tt, "%q then %q", test.first, test.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBwTimetableSetErrorKeepsPrevious(t *testing.T) {
|
||||||
|
for _, in := range []string{
|
||||||
|
"Mon-11:00,333 bad",
|
||||||
|
"Mon-11:00,333 Tue-13:40,bad",
|
||||||
|
"Mon-11:00,333 24:01,666",
|
||||||
|
"11:00,333;bad",
|
||||||
|
} {
|
||||||
|
tt := BwTimetable{}
|
||||||
|
require.NoError(t, tt.Set("Sun-20:00,10M"))
|
||||||
|
require.Error(t, tt.Set(in), in)
|
||||||
|
assert.Equal(t, "Sun-20:00,10Mi", tt.String(), in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBwTimetableUnmarshalJSONReplaces(t *testing.T) {
|
||||||
|
var tt BwTimetable
|
||||||
|
require.NoError(t, json.Unmarshal([]byte(`"Sun-00:00,10M"`), &tt))
|
||||||
|
require.NoError(t, json.Unmarshal([]byte(`"Mon-10:00,1M"`), &tt))
|
||||||
|
assert.Equal(t, BwTimetable{
|
||||||
|
BwTimeSlot{DayOfTheWeek: 1, HHMM: 1000, Bandwidth: BwPair{Tx: 1024 * 1024, Rx: 1024 * 1024}},
|
||||||
|
}, tt)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBwTimetableLimitAt(t *testing.T) {
|
func TestBwTimetableLimitAt(t *testing.T) {
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
tt BwTimetable
|
tt BwTimetable
|
||||||
|
|||||||
Reference in New Issue
Block a user