Skip to content

Commit

Permalink
remove top level constructor functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
pgier committed May 30, 2019
1 parent 65bdadf commit 985b823
Show file tree
Hide file tree
Showing 38 changed files with 123 additions and 168 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ fs, err := procfs.NewFS("/proc")
stats, err := fs.NewStat()
```

Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.

```go
fs, err := blockdevice.NewFS("/proc", "/sys")
stats, err := fs.ProcDiskstats()
```

## Building and Testing

The procfs library is normally built as part of another application. However, when making
Expand All @@ -30,7 +37,7 @@ changes to the library, the `make test` command can be used to run the API test
### Updating Test Fixtures

The procfs library includes a set of test fixtures which include many example files from
the `/proc` and `/sys` filesystems. These fixtures are included as a ttar (text tar) file
the `/proc` and `/sys` filesystems. These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file
which is extracted automatically during testing. To add/update the test fixtures, first
ensure the `fixtures` directory is up to date by removing the existing directory and then
extracting the ttar file using `make fixtures/.unpacked` or just `make test`.
Expand Down
6 changes: 6 additions & 0 deletions bcache/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ type FS struct {
sys *fs.FS
}

// NewDefaultFS returns a new Bcache using the default sys fs mount point. It will error
// if the mount point can't be read.
func NewDefaultFS() (FS, error) {
return NewFS(fs.DefaultSysMountPoint)
}

// NewFS returns a new Bcache using the given sys fs mount point. It will error
// if the mount point can't be read.
func NewFS(mountPoint string) (FS, error) {
Expand Down
6 changes: 6 additions & 0 deletions blockdevice/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ type FS struct {
sys *fs.FS
}

// NewDefaultFS returns a new blockdevice fs using the default mountPoints for proc and sys.
// It will error if either of these mount points can't be read.
func NewDefaultFS() (FS, error) {
return NewFS(fs.DefaultProcMountPoint, fs.DefaultSysMountPoint)
}

// NewFS returns a new blockdevice fs using the given mountPoints for proc and sys.
// It will error if either of these mount points can't be read.
func NewFS(procMountPoint string, sysMountPoint string) (FS, error) {
Expand Down
12 changes: 1 addition & 11 deletions buddyinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,8 @@ type BuddyInfo struct {
Sizes []float64
}

// NewBuddyInfo reads the buddyinfo statistics.
func NewBuddyInfo() ([]BuddyInfo, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return nil, err
}

return fs.NewBuddyInfo()
}

// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
file, err := os.Open(fs.proc.Path("buddyinfo"))
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion buddyinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
)

func TestBuddyInfo(t *testing.T) {
buddyInfo, err := getProcFixtures(t).NewBuddyInfo()
buddyInfo, err := getProcFixtures(t).BuddyInfo()
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 6 additions & 0 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ type FS struct {
// DefaultMountPoint is the common mount point of the proc filesystem.
const DefaultMountPoint = fs.DefaultProcMountPoint

// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.
// It will error if the mount point directory can't be read or is a file.
func NewDefaultFS() (FS, error) {
return NewFS(DefaultMountPoint)
}

// NewFS returns a new proc FS mounted under the given proc mountPoint. It will error
// if the mount point directory can't be read or is a file.
func NewFS(mountPoint string) (FS, error) {
Expand Down
28 changes: 4 additions & 24 deletions ipvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,8 @@ type IPVSBackendStatus struct {
Weight uint64
}

// NewIPVSStats reads the IPVS statistics.
func NewIPVSStats() (IPVSStats, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return IPVSStats{}, err
}

return fs.NewIPVSStats()
}

// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
func (fs FS) NewIPVSStats() (IPVSStats, error) {
// IPVSStats reads the IPVS statistics from the specified `proc` filesystem.
func (fs FS) IPVSStats() (IPVSStats, error) {
file, err := os.Open(fs.proc.Path("net/ip_vs_stats"))
if err != nil {
return IPVSStats{}, err
Expand Down Expand Up @@ -131,18 +121,8 @@ func parseIPVSStats(file io.Reader) (IPVSStats, error) {
return stats, nil
}

// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return []IPVSBackendStatus{}, err
}

return fs.NewIPVSBackendStatus()
}

// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {
file, err := os.Open(fs.proc.Path("net/ip_vs"))
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions ipvs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func TestIPVSStats(t *testing.T) {
if err != nil {
t.Fatal(err)
}
stats, err := fs.NewIPVSStats()
stats, err := fs.IPVSStats()
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -217,7 +217,7 @@ func TestParseIPPortIPv6(t *testing.T) {
}

func TestIPVSBackendStatus(t *testing.T) {
backendStats, err := getProcFixtures(t).NewIPVSBackendStatus()
backendStats, err := getProcFixtures(t).IPVSBackendStatus()
if err != nil {
t.Fatal(err)
}
Expand Down
1 change: 1 addition & 0 deletions mdstat.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type MDStat struct {
}

// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
// TODO: this should just be called "MDStat" and use a separate parseMDStat function
func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
mdStatusFilePath := fs.proc.Path("mdstat")
content, err := ioutil.ReadFile(mdStatusFilePath)
Expand Down
2 changes: 1 addition & 1 deletion mountstats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ func TestMountStats(t *testing.T) {
if tt.s != "" {
mounts, err = parseMountStats(strings.NewReader(tt.s))
} else {
proc, e := getProcFixtures(t).NewProc(26231)
proc, e := getProcFixtures(t).Proc(26231)
if e != nil {
t.Fatalf("failed to create proc: %v", err)
}
Expand Down
18 changes: 4 additions & 14 deletions net_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,13 @@ type NetDevLine struct {
// are interface names.
type NetDev map[string]NetDevLine

// NewNetDev returns kernel/system statistics read from /proc/net/dev.
func NewNetDev() (NetDev, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return nil, err
}

return fs.NewNetDev()
}

// NewNetDev returns kernel/system statistics read from /proc/net/dev.
func (fs FS) NewNetDev() (NetDev, error) {
// NetDev returns kernel/system statistics read from /proc/net/dev.
func (fs FS) NetDev() (NetDev, error) {
return newNetDev(fs.proc.Path("net/dev"))
}

// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
func (p Proc) NewNetDev() (NetDev, error) {
// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
func (p Proc) NetDev() (NetDev, error) {
return newNetDev(p.path("net/dev"))
}

Expand Down
10 changes: 5 additions & 5 deletions net_dev_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ func TestNetDevParseLine(t *testing.T) {
}
}

func TestNewNetDev(t *testing.T) {
func TestNetDev(t *testing.T) {
fs, err := NewFS(procTestFixtures)
if err != nil {
t.Fatal(err)
}

netDev, err := fs.NewNetDev()
netDev, err := fs.NetDev()
if err != nil {
t.Fatal(err)
}
Expand All @@ -59,13 +59,13 @@ func TestNewNetDev(t *testing.T) {
}
}

func TestProcNewNetDev(t *testing.T) {
p, err := getProcFixtures(t).NewProc(26231)
func TestProcNetDev(t *testing.T) {
p, err := getProcFixtures(t).Proc(26231)
if err != nil {
t.Fatal(err)
}

netDev, err := p.NewNetDev()
netDev, err := p.NetDev()
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 6 additions & 0 deletions nfs/nfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ type FS struct {
proc *fs.FS
}

// NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
// if the mount point can't be read.
func NewDefaultFS() (FS, error) {
return NewFS(fs.DefaultProcMountPoint)
}

// NewFS returns a new FS mounted under the given mountPoint. It will error
// if the mount point can't be read.
func NewFS(mountPoint string) (FS, error) {
Expand Down
8 changes: 4 additions & 4 deletions proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func NewProc(pid int) (Proc, error) {
if err != nil {
return Proc{}, err
}
return fs.NewProc(pid)
return fs.Proc(pid)
}

// AllProcs returns a list of all currently available processes under /proc.
Expand All @@ -76,11 +76,11 @@ func (fs FS) Self() (Proc, error) {
if err != nil {
return Proc{}, err
}
return fs.NewProc(pid)
return fs.Proc(pid)
}

// NewProc returns a process for the given pid.
func (fs FS) NewProc(pid int) (Proc, error) {
// Proc returns a process for the given pid.
func (fs FS) Proc(pid int) (Proc, error) {
if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {
return Proc{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions proc_io.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ type ProcIO struct {
CancelledWriteBytes int64
}

// NewIO creates a new ProcIO instance from a given Proc instance.
func (p Proc) NewIO() (ProcIO, error) {
// IO creates a new ProcIO instance from a given Proc instance.
func (p Proc) IO() (ProcIO, error) {
pio := ProcIO{}

f, err := os.Open(p.path("io"))
Expand Down
4 changes: 2 additions & 2 deletions proc_io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ package procfs
import "testing"

func TestProcIO(t *testing.T) {
p, err := getProcFixtures(t).NewProc(26231)
p, err := getProcFixtures(t).Proc(26231)
if err != nil {
t.Fatal(err)
}

s, err := p.NewIO()
s, err := p.IO()
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions proc_limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ var (
limitsDelimiter = regexp.MustCompile(" +")
)

// NewLimits returns the current soft limits of the process.
func (p Proc) NewLimits() (ProcLimits, error) {
// Limits returns the current soft limits of the process.
func (p Proc) Limits() (ProcLimits, error) {
f, err := os.Open(p.path("limits"))
if err != nil {
return ProcLimits{}, err
Expand Down
6 changes: 3 additions & 3 deletions proc_limits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ package procfs

import "testing"

func TestNewLimits(t *testing.T) {
p, err := getProcFixtures(t).NewProc(26231)
func TestLimits(t *testing.T) {
p, err := getProcFixtures(t).Proc(26231)
if err != nil {
t.Fatal(err)
}

l, err := p.NewLimits()
l, err := p.Limits()
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions proc_ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ type Namespace struct {
// Namespaces contains all of the namespaces that the process is contained in.
type Namespaces map[string]Namespace

// NewNamespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
// Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
// process is a member.
func (p Proc) NewNamespaces() (Namespaces, error) {
func (p Proc) Namespaces() (Namespaces, error) {
d, err := os.Open(p.path("ns"))
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions proc_ns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import (
)

func TestNewNamespaces(t *testing.T) {
p, err := getProcFixtures(t).NewProc(26231)
p, err := getProcFixtures(t).Proc(26231)
if err != nil {
t.Fatal(err)
}

namespaces, err := p.NewNamespaces()
namespaces, err := p.Namespaces()
if err != nil {
t.Fatal(err)
}
Expand Down
17 changes: 4 additions & 13 deletions proc_psi.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,10 @@ type PSIStats struct {
Full *PSILine
}

// NewPSIStatsForResource reads pressure stall information for the specified
// resource. At time of writing this can be either "cpu", "memory" or "io".
func NewPSIStatsForResource(resource string) (PSIStats, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return PSIStats{}, err
}

return fs.NewPSIStatsForResource(resource)
}

// NewPSIStatsForResource reads pressure stall information from /proc/pressure/<resource>
func (fs FS) NewPSIStatsForResource(resource string) (PSIStats, error) {
// PSIStatsForResource reads pressure stall information for the specified
// resource from /proc/pressure/<resource>. At time of writing this can be
// either "cpu", "memory" or "io".
func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
file, err := os.Open(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
if err != nil {
return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %s", resource)
Expand Down
6 changes: 3 additions & 3 deletions proc_psi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func TestPSIStats(t *testing.T) {
t.Run("fake", func(*testing.T) {
stats, err := getProcFixtures(t).NewPSIStatsForResource("fake")
stats, err := getProcFixtures(t).PSIStatsForResource("fake")
if err == nil {
t.Fatal("fake resource does not have PSI statistics")
}
Expand All @@ -31,7 +31,7 @@ func TestPSIStats(t *testing.T) {
})

t.Run("cpu", func(t *testing.T) {
stats, err := getProcFixtures(t).NewPSIStatsForResource("cpu")
stats, err := getProcFixtures(t).PSIStatsForResource("cpu")
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -68,7 +68,7 @@ func TestPSIStats(t *testing.T) {

for _, resource := range res {
t.Run(resource, func(t *testing.T) {
stats, err := getProcFixtures(t).NewPSIStatsForResource(resource)
stats, err := getProcFixtures(t).PSIStatsForResource(resource)
if err != nil {
t.Fatal(err)
}
Expand Down
Loading

2 comments on commit 985b823

@yonatan-shorani
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterbourgon
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who approved this?

Please sign in to comment.