diff --git a/cgroups/fs/cpu.go b/cgroups/fs/cpu.go index 2664811..6a7f66c 100644 --- a/cgroups/fs/cpu.go +++ b/cgroups/fs/cpu.go @@ -1,6 +1,9 @@ package fs import ( + "bufio" + "os" + "path/filepath" "strconv" ) @@ -37,7 +40,25 @@ func (s *cpuGroup) Remove(d *data) error { } func (s *cpuGroup) Stats(d *data) (map[string]float64, error) { - // we can reuse the cpuacct subsystem to get the cpu stats - sys := subsystems["cpuacct"] - return sys.Stats(d) + paramData := make(map[string]float64) + path, err := d.path("cpu") + if err != nil { + return nil, err + } + + f, err := os.Open(filepath.Join(path, "cpu.stat")) + if err != nil { + return nil, err + } + defer f.Close() + + sc := bufio.NewScanner(f) + for sc.Scan() { + t, v, err := getCgroupParamKeyValue(sc.Text()) + if err != nil { + return nil, err + } + paramData[t] = v + } + return paramData, nil } diff --git a/cgroups/fs/cpu_test.go b/cgroups/fs/cpu_test.go new file mode 100644 index 0000000..698ae92 --- /dev/null +++ b/cgroups/fs/cpu_test.go @@ -0,0 +1,57 @@ +package fs + +import ( + "testing" +) + +func TestCpuStats(t *testing.T) { + helper := NewCgroupTestUtil("cpu", t) + defer helper.cleanup() + cpuStatContent := `nr_periods 2000 + nr_throttled 200 + throttled_time 42424242424` + helper.writeFileContents(map[string]string{ + "cpu.stat": cpuStatContent, + }) + + cpu := &cpuGroup{} + stats, err := cpu.Stats(helper.CgroupData) + if err != nil { + t.Fatal(err) + } + + expected_stats := map[string]float64{ + "nr_periods": 2000.0, + "nr_throttled": 200.0, + "throttled_time": 42424242424.0, + } + expectStats(t, expected_stats, stats) +} + +func TestNoCpuStatFile(t *testing.T) { + helper := NewCgroupTestUtil("cpu", t) + defer helper.cleanup() + + cpu := &cpuGroup{} + _, err := cpu.Stats(helper.CgroupData) + if err == nil { + t.Fatal("Expected to fail, but did not.") + } +} + +func TestInvalidCpuStat(t *testing.T) { + helper := NewCgroupTestUtil("cpu", t) + defer helper.cleanup() + cpuStatContent := `nr_periods 2000 + nr_throttled 200 + throttled_time fortytwo` + helper.writeFileContents(map[string]string{ + "cpu.stat": cpuStatContent, + }) + + cpu := &cpuGroup{} + _, err := cpu.Stats(helper.CgroupData) + if err == nil { + t.Fatal("Expected failed stat parsing.") + } +}