cpuset.Parse: Fix edge cases and add negative tests

The cpuset.Parse function missed a couple bad input cases, specifically
"1--3" and "10-6".  These were silently ignored when they should instead
be flagged as invalid.

This now catches these cases and expands the unit tests for cpuset to
cover them (and other negative test cases as well).

Signed-off-by: Jim Ramsay <jramsay@redhat.com>
This commit is contained in:
Jim Ramsay 2021-03-25 15:03:08 -04:00
parent 5ab4b580de
commit a21179ae69
2 changed files with 27 additions and 3 deletions

View File

@ -301,7 +301,7 @@ func Parse(s string) (CPUSet, error) {
ranges := strings.Split(s, ",")
for _, r := range ranges {
boundaries := strings.Split(r, "-")
boundaries := strings.SplitN(r, "-", 2)
if len(boundaries) == 1 {
// Handle ranges that consist of only one element like "34".
elem, err := strconv.Atoi(boundaries[0])
@ -319,6 +319,11 @@ func Parse(s string) (CPUSet, error) {
if err != nil {
return NewCPUSet(), err
}
if start > end {
return NewCPUSet(), fmt.Errorf("invalid range %q (%d >= %d)", r, start, end)
}
// start == end is acceptable (1-1 -> 1)
// Add all elements to the result.
// e.g. "0-5", "46-48" => [0, 1, 2, 3, 4, 5, 46, 47, 48].
for e := start; e <= end; e++ {

View File

@ -323,7 +323,7 @@ func TestCPUSetString(t *testing.T) {
}
func TestParse(t *testing.T) {
testCases := []struct {
positiveTestCases := []struct {
cpusetString string
expected CPUSet
}{
@ -332,9 +332,12 @@ func TestParse(t *testing.T) {
{"1,2,3,4,5", NewCPUSet(1, 2, 3, 4, 5)},
{"1-5", NewCPUSet(1, 2, 3, 4, 5)},
{"1-2,3-5", NewCPUSet(1, 2, 3, 4, 5)},
{"5,4,3,2,1", NewCPUSet(1, 2, 3, 4, 5)}, // Range ordering
{"3-6,1-5", NewCPUSet(1, 2, 3, 4, 5, 6)}, // Overlapping ranges
{"3-3,5-5", NewCPUSet(3, 5)}, // Very short ranges
}
for _, c := range testCases {
for _, c := range positiveTestCases {
result, err := Parse(c.cpusetString)
if err != nil {
t.Fatalf("expected error not to have occurred: %v", err)
@ -343,4 +346,20 @@ func TestParse(t *testing.T) {
t.Fatalf("expected string \"%s\" to parse as [%v] (got [%v])", c.cpusetString, c.expected, result)
}
}
negativeTestCases := []string{
// Non-numeric entries
"nonnumeric", "non-numeric", "no,numbers", "0-a", "a-0", "0,a", "a,0", "1-2,a,3-5",
// Incomplete sequences
"0,", "0,,", ",3", ",,3", "0,,3",
// Incomplete ranges and/or negative numbers
"-1", "1-", "1,2-,3", "1,-2,3", "-1--2", "--1", "1--",
// Reversed ranges
"3-0", "0--3"}
for _, c := range negativeTestCases {
result, err := Parse(c)
if err == nil {
t.Fatalf("expected parse failure of \"%s\", but it succeeded as \"%s\"", c, result.String())
}
}
}