Codebase list golang-procfs / 985b823
remove top level constructor functions This removes top level 'New<Thing>' constructor functions in order to make the API slightly smaller and more consistent. Fixes issue #44 Also includes some minor readme and godoc updates. Signed-off-by: Paul Gier <pgier@redhat.com> Paul Gier 4 years ago
38 changed file(s) with 125 addition(s) and 170 deletion(s). Raw diff Collapse all Expand all
2121 stats, err := fs.NewStat()
2222 ```
2323
24 Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.
25
26 ```go
27 fs, err := blockdevice.NewFS("/proc", "/sys")
28 stats, err := fs.ProcDiskstats()
29 ```
30
2431 ## Building and Testing
2532
2633 The procfs library is normally built as part of another application. However, when making
2936 ### Updating Test Fixtures
3037
3138 The procfs library includes a set of test fixtures which include many example files from
32 the `/proc` and `/sys` filesystems. These fixtures are included as a ttar (text tar) file
39 the `/proc` and `/sys` filesystems. These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file
3340 which is extracted automatically during testing. To add/update the test fixtures, first
3441 ensure the `fixtures` directory is up to date by removing the existing directory and then
3542 extracting the ttar file using `make fixtures/.unpacked` or just `make test`.
3131 sys *fs.FS
3232 }
3333
34 // NewDefaultFS returns a new Bcache using the default sys fs mount point. It will error
35 // if the mount point can't be read.
36 func NewDefaultFS() (FS, error) {
37 return NewFS(fs.DefaultSysMountPoint)
38 }
39
3440 // NewFS returns a new Bcache using the given sys fs mount point. It will error
3541 // if the mount point can't be read.
3642 func NewFS(mountPoint string) (FS, error) {
9494 sys *fs.FS
9595 }
9696
97 // NewDefaultFS returns a new blockdevice fs using the default mountPoints for proc and sys.
98 // It will error if either of these mount points can't be read.
99 func NewDefaultFS() (FS, error) {
100 return NewFS(fs.DefaultProcMountPoint, fs.DefaultSysMountPoint)
101 }
102
97103 // NewFS returns a new blockdevice fs using the given mountPoints for proc and sys.
98104 // It will error if either of these mount points can't be read.
99105 func NewFS(procMountPoint string, sysMountPoint string) (FS, error) {
3030 Sizes []float64
3131 }
3232
33 // NewBuddyInfo reads the buddyinfo statistics.
34 func NewBuddyInfo() ([]BuddyInfo, error) {
35 fs, err := NewFS(DefaultMountPoint)
36 if err != nil {
37 return nil, err
38 }
39
40 return fs.NewBuddyInfo()
41 }
42
4333 // NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
44 func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
34 func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
4535 file, err := os.Open(fs.proc.Path("buddyinfo"))
4636 if err != nil {
4737 return nil, err
1818 )
1919
2020 func TestBuddyInfo(t *testing.T) {
21 buddyInfo, err := getProcFixtures(t).NewBuddyInfo()
21 buddyInfo, err := getProcFixtures(t).BuddyInfo()
2222 if err != nil {
2323 t.Fatal(err)
2424 }
2525 // DefaultMountPoint is the common mount point of the proc filesystem.
2626 const DefaultMountPoint = fs.DefaultProcMountPoint
2727
28 // NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.
29 // It will error if the mount point directory can't be read or is a file.
30 func NewDefaultFS() (FS, error) {
31 return NewFS(DefaultMountPoint)
32 }
33
2834 // NewFS returns a new proc FS mounted under the given proc mountPoint. It will error
2935 // if the mount point directory can't be read or is a file.
3036 func NewFS(mountPoint string) (FS, error) {
6161 Weight uint64
6262 }
6363
64 // NewIPVSStats reads the IPVS statistics.
65 func NewIPVSStats() (IPVSStats, error) {
66 fs, err := NewFS(DefaultMountPoint)
67 if err != nil {
68 return IPVSStats{}, err
69 }
70
71 return fs.NewIPVSStats()
72 }
73
74 // NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
75 func (fs FS) NewIPVSStats() (IPVSStats, error) {
64 // IPVSStats reads the IPVS statistics from the specified `proc` filesystem.
65 func (fs FS) IPVSStats() (IPVSStats, error) {
7666 file, err := os.Open(fs.proc.Path("net/ip_vs_stats"))
7767 if err != nil {
7868 return IPVSStats{}, err
130120 return stats, nil
131121 }
132122
133 // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
134 func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
135 fs, err := NewFS(DefaultMountPoint)
136 if err != nil {
137 return []IPVSBackendStatus{}, err
138 }
139
140 return fs.NewIPVSBackendStatus()
141 }
142
143 // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
144 func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
123 // IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
124 func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {
145125 file, err := os.Open(fs.proc.Path("net/ip_vs"))
146126 if err != nil {
147127 return nil, err
162162 if err != nil {
163163 t.Fatal(err)
164164 }
165 stats, err := fs.NewIPVSStats()
165 stats, err := fs.IPVSStats()
166166 if err != nil {
167167 t.Fatal(err)
168168 }
216216 }
217217
218218 func TestIPVSBackendStatus(t *testing.T) {
219 backendStats, err := getProcFixtures(t).NewIPVSBackendStatus()
219 backendStats, err := getProcFixtures(t).IPVSBackendStatus()
220220 if err != nil {
221221 t.Fatal(err)
222222 }
4242 }
4343
4444 // ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
45 // TODO: this should just be called "MDStat" and use a separate parseMDStat function
4546 func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
4647 mdStatusFilePath := fs.proc.Path("mdstat")
4748 content, err := ioutil.ReadFile(mdStatusFilePath)
360360 if tt.s != "" {
361361 mounts, err = parseMountStats(strings.NewReader(tt.s))
362362 } else {
363 proc, e := getProcFixtures(t).NewProc(26231)
363 proc, e := getProcFixtures(t).Proc(26231)
364364 if e != nil {
365365 t.Fatalf("failed to create proc: %v", err)
366366 }
4646 // are interface names.
4747 type NetDev map[string]NetDevLine
4848
49 // NewNetDev returns kernel/system statistics read from /proc/net/dev.
50 func NewNetDev() (NetDev, error) {
51 fs, err := NewFS(DefaultMountPoint)
52 if err != nil {
53 return nil, err
54 }
55
56 return fs.NewNetDev()
57 }
58
59 // NewNetDev returns kernel/system statistics read from /proc/net/dev.
60 func (fs FS) NewNetDev() (NetDev, error) {
49 // NetDev returns kernel/system statistics read from /proc/net/dev.
50 func (fs FS) NetDev() (NetDev, error) {
6151 return newNetDev(fs.proc.Path("net/dev"))
6252 }
6353
64 // NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
65 func (p Proc) NewNetDev() (NetDev, error) {
54 // NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
55 func (p Proc) NetDev() (NetDev, error) {
6656 return newNetDev(p.path("net/dev"))
6757 }
6858
3030 }
3131 }
3232
33 func TestNewNetDev(t *testing.T) {
33 func TestNetDev(t *testing.T) {
3434 fs, err := NewFS(procTestFixtures)
3535 if err != nil {
3636 t.Fatal(err)
3737 }
3838
39 netDev, err := fs.NewNetDev()
39 netDev, err := fs.NetDev()
4040 if err != nil {
4141 t.Fatal(err)
4242 }
5858 }
5959 }
6060
61 func TestProcNewNetDev(t *testing.T) {
62 p, err := getProcFixtures(t).NewProc(26231)
61 func TestProcNetDev(t *testing.T) {
62 p, err := getProcFixtures(t).Proc(26231)
6363 if err != nil {
6464 t.Fatal(err)
6565 }
6666
67 netDev, err := p.NewNetDev()
67 netDev, err := p.NetDev()
6868 if err != nil {
6969 t.Fatal(err)
7070 }
274274 proc *fs.FS
275275 }
276276
277 // NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
278 // if the mount point can't be read.
279 func NewDefaultFS() (FS, error) {
280 return NewFS(fs.DefaultProcMountPoint)
281 }
282
277283 // NewFS returns a new FS mounted under the given mountPoint. It will error
278284 // if the mount point can't be read.
279285 func NewFS(mountPoint string) (FS, error) {
5353 if err != nil {
5454 return Proc{}, err
5555 }
56 return fs.NewProc(pid)
56 return fs.Proc(pid)
5757 }
5858
5959 // AllProcs returns a list of all currently available processes under /proc.
7575 if err != nil {
7676 return Proc{}, err
7777 }
78 return fs.NewProc(pid)
79 }
80
81 // NewProc returns a process for the given pid.
82 func (fs FS) NewProc(pid int) (Proc, error) {
78 return fs.Proc(pid)
79 }
80
81 // Proc returns a process for the given pid.
82 func (fs FS) Proc(pid int) (Proc, error) {
8383 if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {
8484 return Proc{}, err
8585 }
3838 CancelledWriteBytes int64
3939 }
4040
41 // NewIO creates a new ProcIO instance from a given Proc instance.
42 func (p Proc) NewIO() (ProcIO, error) {
41 // IO creates a new ProcIO instance from a given Proc instance.
42 func (p Proc) IO() (ProcIO, error) {
4343 pio := ProcIO{}
4444
4545 f, err := os.Open(p.path("io"))
1515 import "testing"
1616
1717 func TestProcIO(t *testing.T) {
18 p, err := getProcFixtures(t).NewProc(26231)
18 p, err := getProcFixtures(t).Proc(26231)
1919 if err != nil {
2020 t.Fatal(err)
2121 }
2222
23 s, err := p.NewIO()
23 s, err := p.IO()
2424 if err != nil {
2525 t.Fatal(err)
2626 }
7676 limitsDelimiter = regexp.MustCompile(" +")
7777 )
7878
79 // NewLimits returns the current soft limits of the process.
80 func (p Proc) NewLimits() (ProcLimits, error) {
79 // Limits returns the current soft limits of the process.
80 func (p Proc) Limits() (ProcLimits, error) {
8181 f, err := os.Open(p.path("limits"))
8282 if err != nil {
8383 return ProcLimits{}, err
1414
1515 import "testing"
1616
17 func TestNewLimits(t *testing.T) {
18 p, err := getProcFixtures(t).NewProc(26231)
17 func TestLimits(t *testing.T) {
18 p, err := getProcFixtures(t).Proc(26231)
1919 if err != nil {
2020 t.Fatal(err)
2121 }
2222
23 l, err := p.NewLimits()
23 l, err := p.Limits()
2424 if err != nil {
2525 t.Fatal(err)
2626 }
2828 // Namespaces contains all of the namespaces that the process is contained in.
2929 type Namespaces map[string]Namespace
3030
31 // NewNamespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
31 // Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
3232 // process is a member.
33 func (p Proc) NewNamespaces() (Namespaces, error) {
33 func (p Proc) Namespaces() (Namespaces, error) {
3434 d, err := os.Open(p.path("ns"))
3535 if err != nil {
3636 return nil, err
1717 )
1818
1919 func TestNewNamespaces(t *testing.T) {
20 p, err := getProcFixtures(t).NewProc(26231)
20 p, err := getProcFixtures(t).Proc(26231)
2121 if err != nil {
2222 t.Fatal(err)
2323 }
2424
25 namespaces, err := p.NewNamespaces()
25 namespaces, err := p.Namespaces()
2626 if err != nil {
2727 t.Fatal(err)
2828 }
5050 Full *PSILine
5151 }
5252
53 // NewPSIStatsForResource reads pressure stall information for the specified
54 // resource. At time of writing this can be either "cpu", "memory" or "io".
55 func NewPSIStatsForResource(resource string) (PSIStats, error) {
56 fs, err := NewFS(DefaultMountPoint)
57 if err != nil {
58 return PSIStats{}, err
59 }
60
61 return fs.NewPSIStatsForResource(resource)
62 }
63
64 // NewPSIStatsForResource reads pressure stall information from /proc/pressure/<resource>
65 func (fs FS) NewPSIStatsForResource(resource string) (PSIStats, error) {
53 // PSIStatsForResource reads pressure stall information for the specified
54 // resource from /proc/pressure/<resource>. At time of writing this can be
55 // either "cpu", "memory" or "io".
56 func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
6657 file, err := os.Open(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
6758 if err != nil {
6859 return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %s", resource)
1919
2020 func TestPSIStats(t *testing.T) {
2121 t.Run("fake", func(*testing.T) {
22 stats, err := getProcFixtures(t).NewPSIStatsForResource("fake")
22 stats, err := getProcFixtures(t).PSIStatsForResource("fake")
2323 if err == nil {
2424 t.Fatal("fake resource does not have PSI statistics")
2525 }
3030 })
3131
3232 t.Run("cpu", func(t *testing.T) {
33 stats, err := getProcFixtures(t).NewPSIStatsForResource("cpu")
33 stats, err := getProcFixtures(t).PSIStatsForResource("cpu")
3434 if err != nil {
3535 t.Fatal(err)
3636 }
6767
6868 for _, resource := range res {
6969 t.Run(resource, func(t *testing.T) {
70 stats, err := getProcFixtures(t).NewPSIStatsForResource(resource)
70 stats, err := getProcFixtures(t).PSIStatsForResource(resource)
7171 if err != nil {
7272 t.Fatal(err)
7373 }
103103 proc fs.FS
104104 }
105105
106 // NewStat returns the current status information of the process.
107 func (p Proc) NewStat() (ProcStat, error) {
106 // Stat returns the current status information of the process.
107 func (p Proc) Stat() (ProcStat, error) {
108108 f, err := os.Open(p.path("stat"))
109109 if err != nil {
110110 return ProcStat{}, err
177177 // StartTime returns the unix timestamp of the process in seconds.
178178 func (s ProcStat) StartTime() (float64, error) {
179179 fs := FS{proc: s.proc}
180 stat, err := fs.NewStat()
180 stat, err := fs.Stat()
181181 if err != nil {
182182 return 0, err
183183 }
1818 )
1919
2020 func TestProcStat(t *testing.T) {
21 p, err := getProcFixtures(t).NewProc(26231)
21 p, err := getProcFixtures(t).Proc(26231)
2222 if err != nil {
2323 t.Fatal(err)
2424 }
2525
26 s, err := p.NewStat()
26 s, err := p.Stat()
2727 if err != nil {
2828 t.Fatal(err)
2929 }
117117 if err != nil {
118118 return ProcStat{}, err
119119 }
120 p, err := fs.NewProc(pid)
120 p, err := fs.Proc(pid)
121121 if err != nil {
122122 return ProcStat{}, err
123123 }
124124
125 return p.NewStat()
125 return p.Stat()
126126 }
1717 )
1818
1919 func TestProcStatus(t *testing.T) {
20 p, err := getProcFixtures(t).NewProc(26231)
20 p, err := getProcFixtures(t).Proc(26231)
2121 if err != nil {
2222 t.Fatal(err)
2323 }
6161 }
6262
6363 func TestProcStatusName(t *testing.T) {
64 p, err := getProcFixtures(t).NewProc(26231)
64 p, err := getProcFixtures(t).Proc(26231)
6565 if err != nil {
6666 t.Fatal(err)
6767 }
2121 func TestSelf(t *testing.T) {
2222 fs := getProcFixtures(t)
2323
24 p1, err := fs.NewProc(26231)
24 p1, err := fs.Proc(26231)
2525 if err != nil {
2626 t.Fatal(err)
2727 }
5757 {process: 26232, want: []string{}},
5858 {process: 26233, want: []string{"com.github.uiautomator"}},
5959 } {
60 p1, err := getProcFixtures(t).NewProc(tt.process)
60 p1, err := getProcFixtures(t).Proc(tt.process)
6161 if err != nil {
6262 t.Fatal(err)
6363 }
7979 {process: 26231, want: "vim"},
8080 {process: 26232, want: "ata_sff"},
8181 } {
82 p1, err := getProcFixtures(t).NewProc(tt.process)
82 p1, err := getProcFixtures(t).Proc(tt.process)
8383 if err != nil {
8484 t.Fatal(err)
8585 }
101101 {process: 26231, want: "/usr/bin/vim"},
102102 {process: 26232, want: ""},
103103 } {
104 p, err := getProcFixtures(t).NewProc(tt.process)
104 p, err := getProcFixtures(t).Proc(tt.process)
105105 if err != nil {
106106 t.Fatal(err)
107107 }
125125 {process: 26232, want: "/does/not/exist", brokenLink: true},
126126 {process: 26233, want: ""},
127127 } {
128 p, err := getProcFixtures(t).NewProc(tt.process)
128 p, err := getProcFixtures(t).Proc(tt.process)
129129 if err != nil {
130130 t.Fatal(err)
131131 }
153153 {process: 26232, want: "/does/not/exist", brokenLink: true},
154154 {process: 26233, want: ""},
155155 } {
156 p, err := getProcFixtures(t).NewProc(tt.process)
156 p, err := getProcFixtures(t).Proc(tt.process)
157157 if err != nil {
158158 t.Fatal(err)
159159 }
172172 }
173173
174174 func TestFileDescriptors(t *testing.T) {
175 p1, err := getProcFixtures(t).NewProc(26231)
175 p1, err := getProcFixtures(t).Proc(26231)
176176 if err != nil {
177177 t.Fatal(err)
178178 }
187187 }
188188
189189 func TestFileDescriptorTargets(t *testing.T) {
190 p1, err := getProcFixtures(t).NewProc(26231)
190 p1, err := getProcFixtures(t).Proc(26231)
191191 if err != nil {
192192 t.Fatal(err)
193193 }
209209 }
210210
211211 func TestFileDescriptorsLen(t *testing.T) {
212 p1, err := getProcFixtures(t).NewProc(26231)
212 p1, err := getProcFixtures(t).Proc(26231)
213213 if err != nil {
214214 t.Fatal(err)
215215 }
7777 SoftIRQ SoftIRQStat
7878 }
7979
80 // NewStat returns kernel/system statistics read from /proc/stat.
81 func NewStat() (Stat, error) {
82 fs, err := NewFS(DefaultMountPoint)
83 if err != nil {
84 return Stat{}, err
85 }
86
87 return fs.NewStat()
88 }
89
9080 // Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
9181 func parseCPUStat(line string) (CPUStat, int64, error) {
9282 cpuStat := CPUStat{}
148138 return softIRQStat, total, nil
149139 }
150140
151 // NewStat returns an information about current kernel/system statistics.
152 func (fs FS) NewStat() (Stat, error) {
141 // Stat returns an information about current kernel/system statistics.
142 func (fs FS) Stat() (Stat, error) {
153143 // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
154144
155145 f, err := os.Open(fs.proc.Path("stat"))
1515 import "testing"
1616
1717 func TestStat(t *testing.T) {
18 s, err := getProcFixtures(t).NewStat()
18 s, err := getProcFixtures(t).Stat()
1919 if err != nil {
2020 t.Fatal(err)
2121 }
101101 // The map keys are the names of the power supplies.
102102 type PowerSupplyClass map[string]PowerSupply
103103
104 // NewPowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
105 func NewPowerSupplyClass() (PowerSupplyClass, error) {
106 fs, err := NewFS(DefaultMountPoint)
107 if err != nil {
108 return nil, err
109 }
110
111 return fs.NewPowerSupplyClass()
112 }
113
114 // NewPowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
115 func (fs FS) NewPowerSupplyClass() (PowerSupplyClass, error) {
104 // PowerSupplyClass returns info for all power supplies read from /sys/class/power_supply/.
105 func (fs FS) PowerSupplyClass() (PowerSupplyClass, error) {
116106 path := fs.sys.Path("class/power_supply")
117107
118108 powerSupplyDirs, err := ioutil.ReadDir(path)
2020 "testing"
2121 )
2222
23 func TestNewPowerSupplyClass(t *testing.T) {
23 func TestPowerSupplyClass(t *testing.T) {
2424 fs, err := NewFS(sysTestFixtures)
2525 if err != nil {
2626 t.Fatal(err)
2727 }
2828
29 psc, err := fs.NewPowerSupplyClass()
29 psc, err := fs.PowerSupplyClass()
3030 if err != nil {
3131 t.Fatal(err)
3232 }
3434 Passive *uint64 // Optional: millidegrees Celsius. (0 for disabled, > 1000 for enabled+value)
3535 }
3636
37 // NewClassThermalZoneStats returns Thermal Zone metrics for all zones.
38 func (fs FS) NewClassThermalZoneStats() ([]ClassThermalZoneStats, error) {
37 // ClassThermalZoneStats returns Thermal Zone metrics for all zones.
38 func (fs FS) ClassThermalZoneStats() ([]ClassThermalZoneStats, error) {
3939 zones, err := filepath.Glob(fs.sys.Path("class/thermal/thermal_zone[0-9]*"))
4040 if err != nil {
4141 return []ClassThermalZoneStats{}, err
2727 t.Fatal(err)
2828 }
2929
30 thermalTest, err := fs.NewClassThermalZoneStats()
30 thermalTest, err := fs.ClassThermalZoneStats()
3131 if err != nil {
3232 t.Fatal(err)
3333 }
2525 // DefaultMountPoint is the common mount point of the sys filesystem.
2626 const DefaultMountPoint = fs.DefaultSysMountPoint
2727
28 // NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
29 // if the mount point can't be read.
30 func NewDefaultFS() (FS, error) {
31 return NewFS(DefaultMountPoint)
32 }
33
2834 // NewFS returns a new FS mounted under the given mountPoint. It will error
2935 // if the mount point can't be read.
3036 func NewFS(mountPoint string) (FS, error) {
6464 // are interface (iface) names.
6565 type NetClass map[string]NetClassIface
6666
67 // NewNetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
68 func NewNetClass() (NetClass, error) {
69 fs, err := NewFS(DefaultMountPoint)
70 if err != nil {
71 return nil, err
72 }
73
74 return fs.NewNetClass()
75 }
76
7767 // NetClassDevices scans /sys/class/net for devices and returns them as a list of names.
7868 func (fs FS) NetClassDevices() ([]string, error) {
7969 var res []string
9484 return res, nil
9585 }
9686
97 // NewNetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
98 func (fs FS) NewNetClass() (NetClass, error) {
87 // NetClass returns info for all net interfaces (iface) read from /sys/class/net/<iface>.
88 func (fs FS) NetClass() (NetClass, error) {
9989 devices, err := fs.NetClassDevices()
10090 if err != nil {
10191 return nil, err
3838 }
3939 }
4040
41 func TestNewNetClass(t *testing.T) {
41 func TestNetClass(t *testing.T) {
4242 fs, err := NewFS(sysTestFixtures)
4343 if err != nil {
4444 t.Fatal(err)
4545 }
4646
47 nc, err := fs.NewNetClass()
47 nc, err := fs.NetClass()
4848 if err != nil {
4949 t.Fatal(err)
5050 }
4545
4646 // TODO: Add thermal_throttle support.
4747
48 // NewSystemCpufreq returns CPU frequency metrics for all CPUs.
49 func NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) {
50 fs, err := NewFS(DefaultMountPoint)
51 if err != nil {
52 return []SystemCPUCpufreqStats{}, err
53 }
54
55 return fs.NewSystemCpufreq()
56 }
57
58 // NewSystemCpufreq returns CPU frequency metrics for all CPUs.
59 func (fs FS) NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) {
48 // SystemCpufreq returns CPU frequency metrics for all CPUs.
49 func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) {
6050 var g errgroup.Group
6151
6252 cpus, err := filepath.Glob(fs.sys.Path("devices/system/cpu/cpu[0-9]*"))
2323 return &v
2424 }
2525
26 func TestNewSystemCpufreq(t *testing.T) {
26 func TestSystemCpufreq(t *testing.T) {
2727 fs, err := NewFS(sysTestFixtures)
2828 if err != nil {
2929 t.Fatal(err)
3030 }
3131
32 c, err := fs.NewSystemCpufreq()
32 c, err := fs.SystemCpufreq()
3333 if err != nil {
3434 t.Fatal(err)
3535 }
176176 sys *fs.FS
177177 }
178178
179 // NewDefaultFS returns a new XFS handle using the default proc and sys mountPoints.
180 // It will error if either of the mounts point can't be read.
181 func NewDefaultFS() (FS, error) {
182 return NewFS(fs.DefaultProcMountPoint, fs.DefaultSysMountPoint)
183 }
184
179185 // NewFS returns a new XFS handle using the given proc and sys mountPoints. It will error
180186 // if either of the mounts point can't be read.
181187 func NewFS(procMountPoint string, sysMountPoint string) (FS, error) {