diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c59088e..be36914 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: build-and-test: strategy: matrix: - go-version: ['1.19', '1.20', '1.21'] + go-version: ['1.18', '1.20', '1.21'] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} diff --git a/go.mod b/go.mod index 056b0b7..589e794 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module github.com/tklauser/numcpus -go 1.13 +go 1.18 require golang.org/x/sys v0.15.0 diff --git a/numcpus_linux.go b/numcpus_linux.go index 1a30525..7e75cb0 100644 --- a/numcpus_linux.go +++ b/numcpus_linux.go @@ -15,7 +15,6 @@ package numcpus import ( - "io/ioutil" "os" "path/filepath" "strconv" @@ -35,7 +34,7 @@ func getFromCPUAffinity() (int, error) { } func readCPURange(file string) (int, error) { - buf, err := ioutil.ReadFile(filepath.Join(sysfsCPUBasePath, file)) + buf, err := os.ReadFile(filepath.Join(sysfsCPUBasePath, file)) if err != nil { return 0, err } @@ -48,16 +47,16 @@ func parseCPURange(cpus string) (int, error) { if len(cpuRange) == 0 { continue } - rangeOp := strings.SplitN(cpuRange, "-", 2) - first, err := strconv.ParseUint(rangeOp[0], 10, 32) + from, to, found := strings.Cut(cpuRange, "-") + first, err := strconv.ParseUint(from, 10, 32) if err != nil { return 0, err } - if len(rangeOp) == 1 { + if !found { n++ continue } - last, err := strconv.ParseUint(rangeOp[1], 10, 32) + last, err := strconv.ParseUint(to, 10, 32) if err != nil { return 0, err } @@ -89,7 +88,7 @@ func getConfigured() (int, error) { } func getKernelMax() (int, error) { - buf, err := ioutil.ReadFile(filepath.Join(sysfsCPUBasePath, "kernel_max")) + buf, err := os.ReadFile(filepath.Join(sysfsCPUBasePath, "kernel_max")) if err != nil { return 0, err } diff --git a/numcpus_linux_test.go b/numcpus_linux_test.go index 0ba9929..0a6a8ec 100644 --- a/numcpus_linux_test.go +++ b/numcpus_linux_test.go @@ -18,37 +18,39 @@ import "testing" func TestParseCPURange(t *testing.T) { testCases := []struct { - cpus string - n int + str string + n int + wantErr bool }{ - {"", 0}, - {"0", 1}, - {"0-1", 2}, - {"0-7", 8}, - {"1-7", 7}, - {"1-15", 15}, - {"0-3,7", 5}, - {"0,2-4", 4}, - {"0,2-4,7", 5}, - {"0,2-4,7-15", 13}, + {str: "", n: 0}, + {str: "0", n: 1}, + {str: "0-1", n: 2}, + {str: "0-7", n: 8}, + {str: "1-7", n: 7}, + {str: "1-15", n: 15}, + {str: "0-3,7", n: 5}, + {str: "0,2-4", n: 4}, + {str: "0,2-4,7", n: 5}, + {str: "0,2-4,7-15", n: 13}, + {str: "0,2-4,6,8-10", n: 8}, + {str: "invalid", n: 0, wantErr: true}, + {str: "0-", n: 0, wantErr: true}, + {str: "0-,1", n: 0, wantErr: true}, + {str: "0,-3,5", n: 0, wantErr: true}, } for _, tc := range testCases { - n, err := parseCPURange(tc.cpus) - if err != nil { - t.Errorf("failed to parse CPU range: %v", err) + n, err := parseCPURange(tc.str) + if !tc.wantErr && err != nil { + t.Errorf("parseCPURange(%q) = %v, expected no error", tc.str, err) + } else if tc.wantErr && err == nil { + t.Errorf("parseCPURange(%q) expected error", tc.str) } if n != tc.n { - t.Errorf("parseCPURange(%q) = %d, expected %d", tc.cpus, n, tc.n) + t.Errorf("parseCPURange(%q) = %d, expected %d", tc.str, n, tc.n) } } - - str := "invalid" - _, err := parseCPURange(str) - if err == nil { - t.Errorf("parseCPURange(%q) unexpectedly succeeded", str) - } } func TestGetFromCPUAffinity(t *testing.T) {