Skip to content

Commit ff077f2

Browse files
Add tests for weight/throttle device opts validators
opts/weightdevice.go and opts/throttledevice.go had no tests, unlike the sibling opts. Add table-driven coverage for ValidateWeightDevice, ValidateThrottleBpsDevice, ValidateThrottleIOpsDevice and the Set/GetList paths, including boundary (weight 0/10/1000/overflow) and error cases. Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
1 parent 7a54334 commit ff077f2

2 files changed

Lines changed: 139 additions & 0 deletions

File tree

opts/throttledevice_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package opts
2+
3+
import (
4+
"testing"
5+
6+
"gotest.tools/v3/assert"
7+
)
8+
9+
func TestValidateThrottleBpsDevice(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
val string
13+
wantErr string
14+
wantPath string
15+
wantRate uint64
16+
}{
17+
{name: "plain integer", val: "/dev/sda:1000", wantPath: "/dev/sda", wantRate: 1000},
18+
{name: "with unit", val: "/dev/sda:1mb", wantPath: "/dev/sda", wantRate: 1048576},
19+
{name: "zero", val: "/dev/sda:0", wantPath: "/dev/sda", wantRate: 0},
20+
{name: "missing colon", val: "/dev/sda", wantErr: "bad format: /dev/sda"},
21+
{name: "empty device", val: ":1mb", wantErr: "bad format: :1mb"},
22+
{name: "missing /dev/ prefix", val: "sda:1mb", wantErr: "bad format for device path: sda:1mb"},
23+
{name: "non-numeric rate", val: "/dev/sda:foo", wantErr: "invalid rate for device"},
24+
}
25+
for _, tc := range tests {
26+
t.Run(tc.name, func(t *testing.T) {
27+
v, err := ValidateThrottleBpsDevice(tc.val)
28+
if tc.wantErr != "" {
29+
assert.ErrorContains(t, err, tc.wantErr)
30+
assert.Assert(t, v == nil)
31+
return
32+
}
33+
assert.NilError(t, err)
34+
assert.Equal(t, v.Path, tc.wantPath)
35+
assert.Equal(t, v.Rate, tc.wantRate)
36+
})
37+
}
38+
}
39+
40+
func TestValidateThrottleIOpsDevice(t *testing.T) {
41+
tests := []struct {
42+
name string
43+
val string
44+
wantErr string
45+
wantPath string
46+
wantRate uint64
47+
}{
48+
{name: "valid integer", val: "/dev/sda:100", wantPath: "/dev/sda", wantRate: 100},
49+
{name: "fractional rejected", val: "/dev/sda:1.5", wantErr: "invalid rate for device"},
50+
{name: "negative rejected", val: "/dev/sda:-5", wantErr: "invalid rate for device"},
51+
{name: "unit suffix rejected (iops are integers)", val: "/dev/sda:1mb", wantErr: "invalid rate for device"},
52+
{name: "missing /dev/ prefix", val: "sda:100", wantErr: "bad format for device path: sda:100"},
53+
}
54+
for _, tc := range tests {
55+
t.Run(tc.name, func(t *testing.T) {
56+
v, err := ValidateThrottleIOpsDevice(tc.val)
57+
if tc.wantErr != "" {
58+
assert.ErrorContains(t, err, tc.wantErr)
59+
assert.Assert(t, v == nil)
60+
return
61+
}
62+
assert.NilError(t, err)
63+
assert.Equal(t, v.Path, tc.wantPath)
64+
assert.Equal(t, v.Rate, tc.wantRate)
65+
})
66+
}
67+
}
68+
69+
func TestThrottledeviceOptSetGetList(t *testing.T) {
70+
opt := NewThrottledeviceOpt(ValidateThrottleBpsDevice)
71+
assert.NilError(t, opt.Set("/dev/sda:1mb"))
72+
assert.NilError(t, opt.Set("/dev/sdb:2mb"))
73+
74+
list := opt.GetList()
75+
assert.Equal(t, len(list), 2)
76+
assert.Equal(t, list[0].Path, "/dev/sda")
77+
assert.Equal(t, list[0].Rate, uint64(1048576))
78+
assert.Equal(t, list[1].Path, "/dev/sdb")
79+
assert.Equal(t, list[1].Rate, uint64(2097152))
80+
81+
assert.ErrorContains(t, opt.Set("/dev/sdc:bad"), "invalid rate for device")
82+
assert.Equal(t, opt.Type(), "list")
83+
}

opts/weightdevice_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package opts
2+
3+
import (
4+
"testing"
5+
6+
"gotest.tools/v3/assert"
7+
)
8+
9+
func TestValidateWeightDevice(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
val string
13+
wantErr string
14+
wantPath string
15+
wantWeight uint16
16+
}{
17+
{name: "valid minimum", val: "/dev/sda:10", wantPath: "/dev/sda", wantWeight: 10},
18+
{name: "valid maximum", val: "/dev/sda:1000", wantPath: "/dev/sda", wantWeight: 1000},
19+
{name: "zero is accepted (unset)", val: "/dev/sda:0", wantPath: "/dev/sda", wantWeight: 0},
20+
{name: "below minimum", val: "/dev/sda:9", wantErr: "invalid weight for device: /dev/sda:9"},
21+
{name: "above maximum", val: "/dev/sda:1001", wantErr: "invalid weight for device: /dev/sda:1001"},
22+
{name: "overflows uint16", val: "/dev/sda:70000", wantErr: "invalid weight for device: /dev/sda:70000"},
23+
{name: "missing colon", val: "/dev/sda", wantErr: "bad format: /dev/sda"},
24+
{name: "empty device", val: ":100", wantErr: "bad format: :100"},
25+
{name: "missing /dev/ prefix", val: "sda:100", wantErr: "bad format for device path: sda:100"},
26+
}
27+
for _, tc := range tests {
28+
t.Run(tc.name, func(t *testing.T) {
29+
v, err := ValidateWeightDevice(tc.val)
30+
if tc.wantErr != "" {
31+
assert.Error(t, err, tc.wantErr)
32+
assert.Assert(t, v == nil)
33+
return
34+
}
35+
assert.NilError(t, err)
36+
assert.Equal(t, v.Path, tc.wantPath)
37+
assert.Equal(t, v.Weight, tc.wantWeight)
38+
})
39+
}
40+
}
41+
42+
func TestWeightdeviceOptSetGetList(t *testing.T) {
43+
opt := NewWeightdeviceOpt(ValidateWeightDevice)
44+
assert.NilError(t, opt.Set("/dev/sda:100"))
45+
assert.NilError(t, opt.Set("/dev/sdb:200"))
46+
47+
list := opt.GetList()
48+
assert.Equal(t, len(list), 2)
49+
assert.Equal(t, list[0].Path, "/dev/sda")
50+
assert.Equal(t, list[0].Weight, uint16(100))
51+
assert.Equal(t, list[1].Path, "/dev/sdb")
52+
assert.Equal(t, list[1].Weight, uint16(200))
53+
54+
assert.Error(t, opt.Set("/dev/sdc:1"), "invalid weight for device: /dev/sdc:1")
55+
assert.Equal(t, opt.Type(), "list")
56+
}

0 commit comments

Comments
 (0)