summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/prometheus/procfs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/prometheus/procfs')
-rw-r--r--vendor/github.com/prometheus/procfs/.travis.yml4
-rw-r--r--vendor/github.com/prometheus/procfs/Makefile16
-rw-r--r--vendor/github.com/prometheus/procfs/bcache/bcache.go84
-rw-r--r--vendor/github.com/prometheus/procfs/bcache/get.go330
-rw-r--r--vendor/github.com/prometheus/procfs/bcache/get_test.go114
-rw-r--r--vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat28
-rw-r--r--vendor/github.com/prometheus/procfs/fixtures/stat2
-rw-r--r--vendor/github.com/prometheus/procfs/stat.go193
-rw-r--r--vendor/github.com/prometheus/procfs/stat_test.go51
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/.gitignore1
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/fixtures.tar.gzbin0 -> 2865 bytes
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sda1/stats/stats1
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sdb1/stats/stats1
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/fs.go26
-rw-r--r--vendor/github.com/prometheus/procfs/sysfs/fs_test.go42
-rw-r--r--vendor/github.com/prometheus/procfs/xfrm.go187
-rw-r--r--vendor/github.com/prometheus/procfs/xfrm_test.go66
17 files changed, 1122 insertions, 24 deletions
diff --git a/vendor/github.com/prometheus/procfs/.travis.yml b/vendor/github.com/prometheus/procfs/.travis.yml
index a9e28bf5d..ee09bb733 100644
--- a/vendor/github.com/prometheus/procfs/.travis.yml
+++ b/vendor/github.com/prometheus/procfs/.travis.yml
@@ -1,5 +1,5 @@
sudo: false
language: go
go:
- - 1.6.4
- - 1.7.4
+ - 1.7.6
+ - 1.8.3
diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile
index c264a49d1..bfa2124eb 100644
--- a/vendor/github.com/prometheus/procfs/Makefile
+++ b/vendor/github.com/prometheus/procfs/Makefile
@@ -1,6 +1,18 @@
-ci:
+ci: fmt lint test
+
+fmt:
! gofmt -l *.go | read nothing
go vet
- go test -v ./...
+
+lint:
go get github.com/golang/lint/golint
golint *.go
+
+test: sysfs/fixtures/.unpacked
+ go test -v ./...
+
+sysfs/fixtures/.unpacked: sysfs/fixtures.tar.gz
+ cd sysfs && tar xzf fixtures.tar.gz
+ touch $@
+
+.PHONY: fmt lint test ci
diff --git a/vendor/github.com/prometheus/procfs/bcache/bcache.go b/vendor/github.com/prometheus/procfs/bcache/bcache.go
new file mode 100644
index 000000000..1db178cec
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/bcache/bcache.go
@@ -0,0 +1,84 @@
+// Copyright 2017 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package bcache provides access to statistics exposed by the bcache (Linux
+// block cache).
+package bcache
+
+// Stats contains bcache runtime statistics, parsed from /sys/fs/bcache/.
+//
+// The names and meanings of each statistic were taken from bcache.txt and
+// files in drivers/md/bcache in the Linux kernel source. Counters are uint64
+// (in-kernel counters are mostly unsigned long).
+type Stats struct {
+ // The name of the bcache used to source these statistics.
+ Name string
+ Bcache BcacheStats
+ Bdevs []BdevStats
+ Caches []CacheStats
+}
+
+// BcacheStats contains statistics tied to a bcache ID.
+type BcacheStats struct {
+ AverageKeySize uint64
+ BtreeCacheSize uint64
+ CacheAvailablePercent uint64
+ Congested uint64
+ RootUsagePercent uint64
+ TreeDepth uint64
+ Internal InternalStats
+ FiveMin PeriodStats
+ Total PeriodStats
+}
+
+// BdevStats contains statistics for one backing device.
+type BdevStats struct {
+ Name string
+ DirtyData uint64
+ FiveMin PeriodStats
+ Total PeriodStats
+}
+
+// CacheStats contains statistics for one cache device.
+type CacheStats struct {
+ Name string
+ IOErrors uint64
+ MetadataWritten uint64
+ Written uint64
+ Priority PriorityStats
+}
+
+// PriorityStats contains statistics from the priority_stats file.
+type PriorityStats struct {
+ UnusedPercent uint64
+ MetadataPercent uint64
+}
+
+// InternalStats contains internal bcache statistics.
+type InternalStats struct {
+ ActiveJournalEntries uint64
+ BtreeNodes uint64
+ BtreeReadAverageDurationNanoSeconds uint64
+ CacheReadRaces uint64
+}
+
+// PeriodStats contains statistics for a time period (5 min or total).
+type PeriodStats struct {
+ Bypassed uint64
+ CacheBypassHits uint64
+ CacheBypassMisses uint64
+ CacheHits uint64
+ CacheMissCollisions uint64
+ CacheMisses uint64
+ CacheReadaheads uint64
+}
diff --git a/vendor/github.com/prometheus/procfs/bcache/get.go b/vendor/github.com/prometheus/procfs/bcache/get.go
new file mode 100644
index 000000000..4d56f3d98
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/bcache/get.go
@@ -0,0 +1,330 @@
+// Copyright 2017 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package bcache
+
+import (
+ "bufio"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+ "strconv"
+ "strings"
+)
+
+// ParsePseudoFloat parses the peculiar format produced by bcache's bch_hprint.
+func parsePseudoFloat(str string) (float64, error) {
+ ss := strings.Split(str, ".")
+
+ intPart, err := strconv.ParseFloat(ss[0], 64)
+ if err != nil {
+ return 0, err
+ }
+
+ if len(ss) == 1 {
+ // Pure integers are fine.
+ return intPart, nil
+ }
+ fracPart, err := strconv.ParseFloat(ss[1], 64)
+ if err != nil {
+ return 0, err
+ }
+ // fracPart is a number between 0 and 1023 divided by 100; it is off
+ // by a small amount. Unexpected bumps in time lines may occur because
+ // for bch_hprint .1 != .10 and .10 > .9 (at least up to Linux
+ // v4.12-rc3).
+
+ // Restore the proper order:
+ fracPart = fracPart / 10.24
+ return intPart + fracPart, nil
+}
+
+// Dehumanize converts a human-readable byte slice into a uint64.
+func dehumanize(hbytes []byte) (uint64, error) {
+ ll := len(hbytes)
+ if ll == 0 {
+ return 0, fmt.Errorf("zero-length reply")
+ }
+ lastByte := hbytes[ll-1]
+ mul := float64(1)
+ var (
+ mant float64
+ err error
+ )
+ // If lastByte is beyond the range of ASCII digits, it must be a
+ // multiplier.
+ if lastByte > 57 {
+ // Remove multiplier from slice.
+ hbytes = hbytes[:len(hbytes)-1]
+
+ const (
+ _ = 1 << (10 * iota)
+ KiB
+ MiB
+ GiB
+ TiB
+ PiB
+ EiB
+ ZiB
+ YiB
+ )
+
+ multipliers := map[rune]float64{
+ // Source for conversion rules:
+ // linux-kernel/drivers/md/bcache/util.c:bch_hprint()
+ 'k': KiB,
+ 'M': MiB,
+ 'G': GiB,
+ 'T': TiB,
+ 'P': PiB,
+ 'E': EiB,
+ 'Z': ZiB,
+ 'Y': YiB,
+ }
+ mul = float64(multipliers[rune(lastByte)])
+ mant, err = parsePseudoFloat(string(hbytes))
+ if err != nil {
+ return 0, err
+ }
+ } else {
+ // Not humanized by bch_hprint
+ mant, err = strconv.ParseFloat(string(hbytes), 64)
+ if err != nil {
+ return 0, err
+ }
+ }
+ res := uint64(mant * mul)
+ return res, nil
+}
+
+type parser struct {
+ uuidPath string
+ subDir string
+ currentDir string
+ err error
+}
+
+func (p *parser) setSubDir(pathElements ...string) {
+ p.subDir = path.Join(pathElements...)
+ p.currentDir = path.Join(p.uuidPath, p.subDir)
+}
+
+func (p *parser) readValue(fileName string) uint64 {
+ if p.err != nil {
+ return 0
+ }
+ path := path.Join(p.currentDir, fileName)
+ byt, err := ioutil.ReadFile(path)
+ if err != nil {
+ p.err = fmt.Errorf("failed to read: %s", path)
+ return 0
+ }
+ // Remove trailing newline.
+ byt = byt[:len(byt)-1]
+ res, err := dehumanize(byt)
+ p.err = err
+ return res
+}
+
+// ParsePriorityStats parses lines from the priority_stats file.
+func parsePriorityStats(line string, ps *PriorityStats) (error) {
+ var (
+ value uint64
+ err error
+ )
+ switch {
+ case strings.HasPrefix(line, "Unused:"):
+ fields := strings.Fields(line)
+ rawValue := fields[len(fields)-1]
+ valueStr := strings.TrimSuffix(rawValue, "%")
+ value, err = strconv.ParseUint(valueStr, 10, 64)
+ if err != nil {
+ return err
+ }
+ ps.UnusedPercent = value
+ case strings.HasPrefix(line, "Metadata:"):
+ fields := strings.Fields(line)
+ rawValue := fields[len(fields)-1]
+ valueStr := strings.TrimSuffix(rawValue, "%")
+ value, err = strconv.ParseUint(valueStr, 10, 64)
+ if err != nil {
+ return err
+ }
+ ps.MetadataPercent = value
+ }
+ return nil
+}
+
+func (p *parser) getPriorityStats() PriorityStats {
+ var res PriorityStats
+
+ if p.err != nil {
+ return res
+ }
+
+ path := path.Join(p.currentDir, "priority_stats")
+
+ file, err := os.Open(path)
+ if err != nil {
+ p.err = fmt.Errorf("failed to read: %s", path)
+ return res
+ }
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ err = parsePriorityStats(scanner.Text(), &res)
+ if err != nil {
+ p.err = fmt.Errorf("failed to parse: %s (%s)", path, err)
+ return res
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ p.err = fmt.Errorf("failed to parse: %s (%s)", path, err)
+ return res
+ }
+ return res
+}
+
+// GetStats collects from sysfs files data tied to one bcache ID.
+func GetStats(uuidPath string) (*Stats, error) {
+ var bs Stats
+
+ par := parser{uuidPath: uuidPath}
+
+ // bcache stats
+
+ // dir <uuidPath>
+ par.setSubDir("")
+ bs.Bcache.AverageKeySize = par.readValue("average_key_size")
+ bs.Bcache.BtreeCacheSize = par.readValue("btree_cache_size")
+ bs.Bcache.CacheAvailablePercent = par.readValue("cache_available_percent")
+ bs.Bcache.Congested = par.readValue("congested")
+ bs.Bcache.RootUsagePercent = par.readValue("root_usage_percent")
+ bs.Bcache.TreeDepth = par.readValue("tree_depth")
+
+ // bcache stats (internal)
+
+ // dir <uuidPath>/internal
+ par.setSubDir("internal")
+ bs.Bcache.Internal.ActiveJournalEntries = par.readValue("active_journal_entries")
+ bs.Bcache.Internal.BtreeNodes = par.readValue("btree_nodes")
+ bs.Bcache.Internal.BtreeReadAverageDurationNanoSeconds = par.readValue("btree_read_average_duration_us")
+ bs.Bcache.Internal.CacheReadRaces = par.readValue("cache_read_races")
+
+ // bcache stats (period)
+
+ // dir <uuidPath>/stats_five_minute
+ par.setSubDir("stats_five_minute")
+ bs.Bcache.FiveMin.Bypassed = par.readValue("bypassed")
+ bs.Bcache.FiveMin.CacheHits = par.readValue("cache_hits")
+
+ bs.Bcache.FiveMin.Bypassed = par.readValue("bypassed")
+ bs.Bcache.FiveMin.CacheBypassHits = par.readValue("cache_bypass_hits")
+ bs.Bcache.FiveMin.CacheBypassMisses = par.readValue("cache_bypass_misses")
+ bs.Bcache.FiveMin.CacheHits = par.readValue("cache_hits")
+ bs.Bcache.FiveMin.CacheMissCollisions = par.readValue("cache_miss_collisions")
+ bs.Bcache.FiveMin.CacheMisses = par.readValue("cache_misses")
+ bs.Bcache.FiveMin.CacheReadaheads = par.readValue("cache_readaheads")
+
+ // dir <uuidPath>/stats_total
+ par.setSubDir("stats_total")
+ bs.Bcache.Total.Bypassed = par.readValue("bypassed")
+ bs.Bcache.Total.CacheHits = par.readValue("cache_hits")
+
+ bs.Bcache.Total.Bypassed = par.readValue("bypassed")
+ bs.Bcache.Total.CacheBypassHits = par.readValue("cache_bypass_hits")
+ bs.Bcache.Total.CacheBypassMisses = par.readValue("cache_bypass_misses")
+ bs.Bcache.Total.CacheHits = par.readValue("cache_hits")
+ bs.Bcache.Total.CacheMissCollisions = par.readValue("cache_miss_collisions")
+ bs.Bcache.Total.CacheMisses = par.readValue("cache_misses")
+ bs.Bcache.Total.CacheReadaheads = par.readValue("cache_readaheads")
+
+ if par.err != nil {
+ return nil, par.err
+ }
+
+ // bdev stats
+
+ reg := path.Join(uuidPath, "bdev[0-9]*")
+ bdevDirs, err := filepath.Glob(reg)
+ if err != nil {
+ return nil, err
+ }
+
+ bs.Bdevs = make([]BdevStats, len(bdevDirs))
+
+ for ii, bdevDir := range bdevDirs {
+ var bds = &bs.Bdevs[ii]
+
+ bds.Name = filepath.Base(bdevDir)
+
+ par.setSubDir(bds.Name)
+ bds.DirtyData = par.readValue("dirty_data")
+
+ // dir <uuidPath>/<bds.Name>/stats_five_minute
+ par.setSubDir(bds.Name, "stats_five_minute")
+ bds.FiveMin.Bypassed = par.readValue("bypassed")
+ bds.FiveMin.CacheBypassHits = par.readValue("cache_bypass_hits")
+ bds.FiveMin.CacheBypassMisses = par.readValue("cache_bypass_misses")
+ bds.FiveMin.CacheHits = par.readValue("cache_hits")
+ bds.FiveMin.CacheMissCollisions = par.readValue("cache_miss_collisions")
+ bds.FiveMin.CacheMisses = par.readValue("cache_misses")
+ bds.FiveMin.CacheReadaheads = par.readValue("cache_readaheads")
+
+ // dir <uuidPath>/<bds.Name>/stats_total
+ par.setSubDir("stats_total")
+ bds.Total.Bypassed = par.readValue("bypassed")
+ bds.Total.CacheBypassHits = par.readValue("cache_bypass_hits")
+ bds.Total.CacheBypassMisses = par.readValue("cache_bypass_misses")
+ bds.Total.CacheHits = par.readValue("cache_hits")
+ bds.Total.CacheMissCollisions = par.readValue("cache_miss_collisions")
+ bds.Total.CacheMisses = par.readValue("cache_misses")
+ bds.Total.CacheReadaheads = par.readValue("cache_readaheads")
+ }
+
+ if par.err != nil {
+ return nil, par.err
+ }
+
+ // cache stats
+
+ reg = path.Join(uuidPath, "cache[0-9]*")
+ cacheDirs, err := filepath.Glob(reg)
+ if err != nil {
+ return nil, err
+ }
+ bs.Caches = make([]CacheStats, len(cacheDirs))
+
+ for ii, cacheDir := range cacheDirs {
+ var cs = &bs.Caches[ii]
+ cs.Name = filepath.Base(cacheDir)
+
+ // dir is <uuidPath>/<cs.Name>
+ par.setSubDir(cs.Name)
+ cs.IOErrors = par.readValue("io_errors")
+ cs.MetadataWritten = par.readValue("metadata_written")
+ cs.Written = par.readValue("written")
+
+ ps := par.getPriorityStats()
+ cs.Priority = ps
+ }
+
+ if par.err != nil {
+ return nil, par.err
+ }
+
+ return &bs, nil
+}
diff --git a/vendor/github.com/prometheus/procfs/bcache/get_test.go b/vendor/github.com/prometheus/procfs/bcache/get_test.go
new file mode 100644
index 000000000..38c3df573
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/bcache/get_test.go
@@ -0,0 +1,114 @@
+// Copyright 2017 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package bcache
+
+import (
+ "testing"
+ "math"
+)
+
+func TestDehumanizeTests(t *testing.T) {
+ dehumanizeTests := []struct {
+ in []byte
+ out uint64
+ invalid bool
+ }{
+ {
+ in: []byte("542k"),
+ out: 555008,
+ },
+ {
+ in: []byte("322M"),
+ out: 337641472,
+ },
+ {
+ in: []byte("1.1k"),
+ out: 1124,
+ },
+ {
+ in: []byte("1.9k"),
+ out: 1924,
+ },
+ {
+ in: []byte("1.10k"),
+ out: 2024,
+ },
+ {
+ in: []byte(""),
+ out: 0,
+ invalid: true,
+ },
+ }
+ for _, tst := range dehumanizeTests {
+ got, err := dehumanize(tst.in)
+ if tst.invalid && err == nil {
+ t.Error("expected an error, but none occurred")
+ }
+ if !tst.invalid && err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if got != tst.out {
+ t.Errorf("dehumanize: '%s', want %f, got %f", tst.in, tst.out, got)
+ }
+ }
+}
+
+func TestParsePseudoFloatTests(t *testing.T) {
+ parsePseudoFloatTests := []struct {
+ in string
+ out float64
+ }{
+ {
+ in: "1.1",
+ out: float64(1.097656),
+ },
+ {
+ in: "1.9",
+ out: float64(1.878906),
+ },
+ {
+ in: "1.10",
+ out: float64(1.976562),
+ },
+ }
+ for _, tst := range parsePseudoFloatTests {
+ got, err := parsePseudoFloat(tst.in)
+ if err != nil || math.Abs(got - tst.out) > 0.0001 {
+ t.Errorf("parsePseudoFloat: %s, want %f, got %f", tst.in, tst.out, got)
+ }
+ }
+}
+
+func TestPriorityStats(t *testing.T) {
+ var want = PriorityStats{
+ UnusedPercent: 99,
+ MetadataPercent: 5,
+ }
+ var (
+ in string
+ gotErr error
+ got PriorityStats
+ )
+ in = "Metadata: 5%"
+ gotErr = parsePriorityStats(in, &got)
+ if gotErr != nil || got.MetadataPercent != want.MetadataPercent {
+ t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.MetadataPercent, got.MetadataPercent)
+ }
+
+ in = "Unused: 99%"
+ gotErr = parsePriorityStats(in, &got)
+ if gotErr != nil || got.UnusedPercent != want.UnusedPercent {
+ t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.UnusedPercent, got.UnusedPercent)
+ }
+}
diff --git a/vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat b/vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat
new file mode 100644
index 000000000..d278ace95
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat
@@ -0,0 +1,28 @@
+XfrmInError 1
+XfrmInBufferError 2
+XfrmInHdrError 4
+XfrmInNoStates 3
+XfrmInStateProtoError 40
+XfrmInStateModeError 100
+XfrmInStateSeqError 6000
+XfrmInStateExpired 4
+XfrmInStateMismatch 23451
+XfrmInStateInvalid 55555
+XfrmInTmplMismatch 51
+XfrmInNoPols 65432
+XfrmInPolBlock 100
+XfrmInPolError 10000
+XfrmOutError 1000000
+XfrmOutBundleGenError 43321
+XfrmOutBundleCheckError 555
+XfrmOutNoStates 869
+XfrmOutStateProtoError 4542
+XfrmOutStateModeError 4
+XfrmOutStateSeqError 543
+XfrmOutStateExpired 565
+XfrmOutPolBlock 43456
+XfrmOutPolDead 7656
+XfrmOutPolError 1454
+XfrmFwdHdrError 6654
+XfrmOutStateInvalid 28765
+XfrmAcquireError 24532
diff --git a/vendor/github.com/prometheus/procfs/fixtures/stat b/vendor/github.com/prometheus/procfs/fixtures/stat
index dabb96f74..1582a8cb5 100644
--- a/vendor/github.com/prometheus/procfs/fixtures/stat
+++ b/vendor/github.com/prometheus/procfs/fixtures/stat
@@ -12,5 +12,5 @@ ctxt 38014093
btime 1418183276
processes 26442
procs_running 2
-procs_blocked 0
+procs_blocked 1
softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444
diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go
index 1ca217e8c..701f4df64 100644
--- a/vendor/github.com/prometheus/procfs/stat.go
+++ b/vendor/github.com/prometheus/procfs/stat.go
@@ -3,15 +3,66 @@ package procfs
import (
"bufio"
"fmt"
+ "io"
"os"
"strconv"
"strings"
)
+// CPUStat shows how much time the cpu spend in various stages.
+type CPUStat struct {
+ User float64
+ Nice float64
+ System float64
+ Idle float64
+ Iowait float64
+ IRQ float64
+ SoftIRQ float64
+ Steal float64
+ Guest float64
+ GuestNice float64
+}
+
+// SoftIRQStat represent the softirq statistics as exported in the procfs stat file.
+// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html
+// It is possible to get per-cpu stats by reading /proc/softirqs
+type SoftIRQStat struct {
+ Hi uint64
+ Timer uint64
+ NetTx uint64
+ NetRx uint64
+ Block uint64
+ BlockIoPoll uint64
+ Tasklet uint64
+ Sched uint64
+ Hrtimer uint64
+ Rcu uint64
+}
+
// Stat represents kernel/system statistics.
type Stat struct {
// Boot time in seconds since the Epoch.
- BootTime int64
+ BootTime uint64
+ // Summed up cpu statistics.
+ CPUTotal CPUStat
+ // Per-CPU statistics.
+ CPU []CPUStat
+ // Number of times interrupts were handled, which contains numbered and unnumbered IRQs.
+ IRQTotal uint64
+ // Number of times a numbered IRQ was triggered.
+ IRQ []uint64
+ // Number of times a context switch happened.
+ ContextSwitches uint64
+ // Number of times a process was created.
+ ProcessCreated uint64
+ // Number of processes currently running.
+ ProcessesRunning uint64
+ // Number of processes currently blocked (waiting for IO).
+ ProcessesBlocked uint64
+ // Number of times a softirq was scheduled.
+ SoftIRQTotal uint64
+ // Detailed softirq statistics.
+ SoftIRQ SoftIRQStat
}
// NewStat returns kernel/system statistics read from /proc/stat.
@@ -24,33 +75,145 @@ func NewStat() (Stat, error) {
return fs.NewStat()
}
+// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
+func parseCPUStat(line string) (CPUStat, int64, error) {
+ cpuStat := CPUStat{}
+ var cpu string
+
+ count, err := fmt.Sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f",
+ &cpu,
+ &cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle,
+ &cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal,
+ &cpuStat.Guest, &cpuStat.GuestNice)
+
+ if err != nil && err != io.EOF {
+ return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): %s", line, err)
+ }
+ if count == 0 {
+ return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): 0 elements parsed", line)
+ }
+
+ cpuStat.User /= userHZ
+ cpuStat.Nice /= userHZ
+ cpuStat.System /= userHZ
+ cpuStat.Idle /= userHZ
+ cpuStat.Iowait /= userHZ
+ cpuStat.IRQ /= userHZ
+ cpuStat.SoftIRQ /= userHZ
+ cpuStat.Steal /= userHZ
+ cpuStat.Guest /= userHZ
+ cpuStat.GuestNice /= userHZ
+
+ if cpu == "cpu" {
+ return cpuStat, -1, nil
+ }
+
+ cpuID, err := strconv.ParseInt(cpu[3:], 10, 64)
+ if err != nil {
+ return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu/cpuid): %s", line, err)
+ }
+
+ return cpuStat, cpuID, nil
+}
+
+// Parse a softirq line.
+func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
+ softIRQStat := SoftIRQStat{}
+ var total uint64
+ var prefix string
+
+ _, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d",
+ &prefix, &total,
+ &softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx,
+ &softIRQStat.Block, &softIRQStat.BlockIoPoll,
+ &softIRQStat.Tasklet, &softIRQStat.Sched,
+ &softIRQStat.Hrtimer, &softIRQStat.Rcu)
+
+ if err != nil {
+ return SoftIRQStat{}, 0, fmt.Errorf("couldn't parse %s (softirq): %s", line, err)
+ }
+
+ return softIRQStat, total, nil
+}
+
// NewStat returns an information about current kernel/system statistics.
func (fs FS) NewStat() (Stat, error) {
+ // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+
f, err := os.Open(fs.Path("stat"))
if err != nil {
return Stat{}, err
}
defer f.Close()
- s := bufio.NewScanner(f)
- for s.Scan() {
- line := s.Text()
- if !strings.HasPrefix(line, "btime") {
+ stat := Stat{}
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ parts := strings.Fields(scanner.Text())
+ // require at least <key> <value>
+ if len(parts) < 2 {
continue
}
- fields := strings.Fields(line)
- if len(fields) != 2 {
- return Stat{}, fmt.Errorf("couldn't parse %s line %s", f.Name(), line)
- }
- i, err := strconv.ParseInt(fields[1], 10, 32)
- if err != nil {
- return Stat{}, fmt.Errorf("couldn't parse %s: %s", fields[1], err)
+ switch {
+ case parts[0] == "btime":
+ if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (btime): %s", parts[1], err)
+ }
+ case parts[0] == "intr":
+ if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (intr): %s", parts[1], err)
+ }
+ numberedIRQs := parts[2:]
+ stat.IRQ = make([]uint64, len(numberedIRQs))
+ for i, count := range numberedIRQs {
+ if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (intr%d): %s", count, i, err)
+ }
+ }
+ case parts[0] == "ctxt":
+ if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (ctxt): %s", parts[1], err)
+ }
+ case parts[0] == "processes":
+ if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (processes): %s", parts[1], err)
+ }
+ case parts[0] == "procs_running":
+ if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (procs_running): %s", parts[1], err)
+ }
+ case parts[0] == "procs_blocked":
+ if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+ return Stat{}, fmt.Errorf("couldn't parse %s (procs_blocked): %s", parts[1], err)
+ }
+ case parts[0] == "softirq":
+ softIRQStats, total, err := parseSoftIRQStat(line)
+ if err != nil {
+ return Stat{}, err
+ }
+ stat.SoftIRQTotal = total
+ stat.SoftIRQ = softIRQStats
+ case strings.HasPrefix(parts[0], "cpu"):
+ cpuStat, cpuID, err := parseCPUStat(line)
+ if err != nil {
+ return Stat{}, err
+ }
+ if cpuID == -1 {
+ stat.CPUTotal = cpuStat
+ } else {
+ for int64(len(stat.CPU)) <= cpuID {
+ stat.CPU = append(stat.CPU, CPUStat{})
+ }
+ stat.CPU[cpuID] = cpuStat
+ }
}
- return Stat{BootTime: i}, nil
}
- if err := s.Err(); err != nil {
+
+ if err := scanner.Err(); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err)
}
- return Stat{}, fmt.Errorf("couldn't parse %s, missing btime", f.Name())
+ return stat, nil
}
diff --git a/vendor/github.com/prometheus/procfs/stat_test.go b/vendor/github.com/prometheus/procfs/stat_test.go
index 6eb792478..c34ccce1a 100644
--- a/vendor/github.com/prometheus/procfs/stat_test.go
+++ b/vendor/github.com/prometheus/procfs/stat_test.go
@@ -8,7 +8,54 @@ func TestStat(t *testing.T) {
t.Fatal(err)
}
- if want, have := int64(1418183276), s.BootTime; want != have {
- t.Errorf("want boot time %d, have %d", want, have)
+ // cpu
+ if want, have := float64(301854)/userHZ, s.CPUTotal.User; want != have {
+ t.Errorf("want cpu/user %v, have %v", want, have)
}
+ if want, have := float64(31)/userHZ, s.CPU[7].SoftIRQ; want != have {
+ t.Errorf("want cpu7/softirq %v, have %v", want, have)
+ }
+
+ // intr
+ if want, have := uint64(8885917), s.IRQTotal; want != have {
+ t.Errorf("want irq/total %d, have %d", want, have)
+ }
+ if want, have := uint64(1), s.IRQ[8]; want != have {
+ t.Errorf("want irq8 %d, have %d", want, have)
+ }
+
+ // ctxt
+ if want, have := uint64(38014093), s.ContextSwitches; want != have {
+ t.Errorf("want context switches (ctxt) %d, have %d", want, have)
+ }
+
+ // btime
+ if want, have := uint64(1418183276), s.BootTime; want != have {
+ t.Errorf("want boot time (btime) %d, have %d", want, have)
+ }
+
+ // processes
+ if want, have := uint64(26442), s.ProcessCreated; want != have {
+ t.Errorf("want process created (processes) %d, have %d", want, have)
+ }
+
+ // procs_running
+ if want, have := uint64(2), s.ProcessesRunning; want != have {
+ t.Errorf("want processes running (procs_running) %d, have %d", want, have)
+ }
+
+ // procs_blocked
+ if want, have := uint64(1), s.ProcessesBlocked; want != have {
+ t.Errorf("want processes blocked (procs_blocked) %d, have %d", want, have)
+ }
+
+ // softirq
+ if want, have := uint64(5057579), s.SoftIRQTotal; want != have {
+ t.Errorf("want softirq total %d, have %d", want, have)
+ }
+
+ if want, have := uint64(508444), s.SoftIRQ.Rcu; want != have {
+ t.Errorf("want softirq RCU %d, have %d", want, have)
+ }
+
}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/.gitignore b/vendor/github.com/prometheus/procfs/sysfs/.gitignore
new file mode 100644
index 000000000..67fc140b9
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/sysfs/.gitignore
@@ -0,0 +1 @@
+fixtures/
diff --git a/vendor/github.com/prometheus/procfs/sysfs/fixtures.tar.gz b/vendor/github.com/prometheus/procfs/sysfs/fixtures.tar.gz
new file mode 100644
index 000000000..88035b7ce
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/sysfs/fixtures.tar.gz
Binary files differ
diff --git a/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sda1/stats/stats b/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sda1/stats/stats
deleted file mode 100644
index 0db7520bf..000000000
--- a/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sda1/stats/stats
+++ /dev/null
@@ -1 +0,0 @@
-extent_alloc 1 0 0 0
diff --git a/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sdb1/stats/stats b/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sdb1/stats/stats
deleted file mode 100644
index 85a038402..000000000
--- a/vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sdb1/stats/stats
+++ /dev/null
@@ -1 +0,0 @@
-extent_alloc 2 0 0 0
diff --git a/vendor/github.com/prometheus/procfs/sysfs/fs.go b/vendor/github.com/prometheus/procfs/sysfs/fs.go
index 8e8380083..fb15d438a 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/fs.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/fs.go
@@ -18,6 +18,7 @@ import (
"os"
"path/filepath"
+ "github.com/prometheus/procfs/bcache"
"github.com/prometheus/procfs/xfs"
)
@@ -80,3 +81,28 @@ func (fs FS) XFSStats() ([]*xfs.Stats, error) {
return stats, nil
}
+
+// BcacheStats retrieves bcache runtime statistics for each bcache.
+func (fs FS) BcacheStats() ([]*bcache.Stats, error) {
+ matches, err := filepath.Glob(fs.Path("fs/bcache/*-*"))
+ if err != nil {
+ return nil, err
+ }
+
+ stats := make([]*bcache.Stats, 0, len(matches))
+ for _, uuidPath := range matches {
+ // "*-*" in glob above indicates the name of the bcache.
+ name := filepath.Base(uuidPath)
+
+ // stats
+ s, err := bcache.GetStats(uuidPath)
+ if err != nil {
+ return nil, err
+ }
+
+ s.Name = name
+ stats = append(stats, s)
+ }
+
+ return stats, nil
+}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/fs_test.go b/vendor/github.com/prometheus/procfs/sysfs/fs_test.go
index d7f2b736b..2b7402eca 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/fs_test.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/fs_test.go
@@ -64,3 +64,45 @@ func TestFSXFSStats(t *testing.T) {
}
}
}
+
+func TestFSBcacheStats(t *testing.T) {
+ stats, err := FS("fixtures").BcacheStats()
+ if err != nil {
+ t.Fatalf("failed to parse bcache stats: %v", err)
+ }
+
+ tests := []struct {
+ name string
+ bdevs int
+ caches int
+ }{
+ {
+ name: "deaddd54-c735-46d5-868e-f331c5fd7c74",
+ bdevs: 1,
+ caches: 1,
+ },
+ }
+
+ const expect = 1
+
+ if l := len(stats); l != expect {
+ t.Fatalf("unexpected number of bcache stats: %d", l)
+ }
+ if l := len(tests); l != expect {
+ t.Fatalf("unexpected number of tests: %d", l)
+ }
+
+ for i, tt := range tests {
+ if want, got := tt.name, stats[i].Name; want != got {
+ t.Errorf("unexpected stats name:\nwant: %q\nhave: %q", want, got)
+ }
+
+ if want, got := tt.bdevs, len(stats[i].Bdevs); want != got {
+ t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got)
+ }
+
+ if want, got := tt.caches, len(stats[i].Caches); want != got {
+ t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got)
+ }
+ }
+}
diff --git a/vendor/github.com/prometheus/procfs/xfrm.go b/vendor/github.com/prometheus/procfs/xfrm.go
new file mode 100644
index 000000000..ffe9df50d
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/xfrm.go
@@ -0,0 +1,187 @@
+// Copyright 2017 Prometheus Team
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// XfrmStat models the contents of /proc/net/xfrm_stat.
+type XfrmStat struct {
+ // All errors which are not matched by other
+ XfrmInError int
+ // No buffer is left
+ XfrmInBufferError int
+ // Header Error
+ XfrmInHdrError int
+ // No state found
+ // i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong
+ XfrmInNoStates int
+ // Transformation protocol specific error
+ // e.g. SA Key is wrong
+ XfrmInStateProtoError int
+ // Transformation mode specific error
+ XfrmInStateModeError int
+ // Sequence error
+ // e.g. sequence number is out of window
+ XfrmInStateSeqError int
+ // State is expired
+ XfrmInStateExpired int
+ // State has mismatch option
+ // e.g. UDP encapsulation type is mismatched
+ XfrmInStateMismatch int
+ // State is invalid
+ XfrmInStateInvalid int
+ // No matching template for states
+ // e.g. Inbound SAs are correct but SP rule is wrong
+ XfrmInTmplMismatch int
+ // No policy is found for states
+ // e.g. Inbound SAs are correct but no SP is found
+ XfrmInNoPols int
+ // Policy discards
+ XfrmInPolBlock int
+ // Policy error
+ XfrmInPolError int
+ // All errors which are not matched by others
+ XfrmOutError int
+ // Bundle generation error
+ XfrmOutBundleGenError int
+ // Bundle check error
+ XfrmOutBundleCheckError int
+ // No state was found
+ XfrmOutNoStates int
+ // Transformation protocol specific error
+ XfrmOutStateProtoError int
+ // Transportation mode specific error
+ XfrmOutStateModeError int
+ // Sequence error
+ // i.e sequence number overflow
+ XfrmOutStateSeqError int
+ // State is expired
+ XfrmOutStateExpired int
+ // Policy discads
+ XfrmOutPolBlock int
+ // Policy is dead
+ XfrmOutPolDead int
+ // Policy Error
+ XfrmOutPolError int
+ XfrmFwdHdrError int
+ XfrmOutStateInvalid int
+ XfrmAcquireError int
+}
+
+// NewXfrmStat reads the xfrm_stat statistics.
+func NewXfrmStat() (XfrmStat, error) {
+ fs, err := NewFS(DefaultMountPoint)
+ if err != nil {
+ return XfrmStat{}, err
+ }
+
+ return fs.NewXfrmStat()
+}
+
+// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
+func (fs FS) NewXfrmStat() (XfrmStat, error) {
+ file, err := os.Open(fs.Path("net/xfrm_stat"))
+ if err != nil {
+ return XfrmStat{}, err
+ }
+ defer file.Close()
+
+ var (
+ x = XfrmStat{}
+ s = bufio.NewScanner(file)
+ )
+
+ for s.Scan() {
+ fields := strings.Fields(s.Text())
+
+ if len(fields) != 2 {
+ return XfrmStat{}, fmt.Errorf(
+ "couldnt parse %s line %s", file.Name(), s.Text())
+ }
+
+ name := fields[0]
+ value, err := strconv.Atoi(fields[1])
+ if err != nil {
+ return XfrmStat{}, err
+ }
+
+ switch name {
+ case "XfrmInError":
+ x.XfrmInError = value
+ case "XfrmInBufferError":
+ x.XfrmInBufferError = value
+ case "XfrmInHdrError":
+ x.XfrmInHdrError = value
+ case "XfrmInNoStates":
+ x.XfrmInNoStates = value
+ case "XfrmInStateProtoError":
+ x.XfrmInStateProtoError = value
+ case "XfrmInStateModeError":
+ x.XfrmInStateModeError = value
+ case "XfrmInStateSeqError":
+ x.XfrmInStateSeqError = value
+ case "XfrmInStateExpired":
+ x.XfrmInStateExpired = value
+ case "XfrmInStateInvalid":
+ x.XfrmInStateInvalid = value
+ case "XfrmInTmplMismatch":
+ x.XfrmInTmplMismatch = value
+ case "XfrmInNoPols":
+ x.XfrmInNoPols = value
+ case "XfrmInPolBlock":
+ x.XfrmInPolBlock = value
+ case "XfrmInPolError":
+ x.XfrmInPolError = value
+ case "XfrmOutError":
+ x.XfrmOutError = value
+ case "XfrmInStateMismatch":
+ x.XfrmInStateMismatch = value
+ case "XfrmOutBundleGenError":
+ x.XfrmOutBundleGenError = value
+ case "XfrmOutBundleCheckError":
+ x.XfrmOutBundleCheckError = value
+ case "XfrmOutNoStates":
+ x.XfrmOutNoStates = value
+ case "XfrmOutStateProtoError":
+ x.XfrmOutStateProtoError = value
+ case "XfrmOutStateModeError":
+ x.XfrmOutStateModeError = value
+ case "XfrmOutStateSeqError":
+ x.XfrmOutStateSeqError = value
+ case "XfrmOutStateExpired":
+ x.XfrmOutStateExpired = value
+ case "XfrmOutPolBlock":
+ x.XfrmOutPolBlock = value
+ case "XfrmOutPolDead":
+ x.XfrmOutPolDead = value
+ case "XfrmOutPolError":
+ x.XfrmOutPolError = value
+ case "XfrmFwdHdrError":
+ x.XfrmFwdHdrError = value
+ case "XfrmOutStateInvalid":
+ x.XfrmOutStateInvalid = value
+ case "XfrmAcquireError":
+ x.XfrmAcquireError = value
+ }
+
+ }
+
+ return x, s.Err()
+}
diff --git a/vendor/github.com/prometheus/procfs/xfrm_test.go b/vendor/github.com/prometheus/procfs/xfrm_test.go
new file mode 100644
index 000000000..5918c390e
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/xfrm_test.go
@@ -0,0 +1,66 @@
+// Copyright 2017 Prometheus Team
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+ "testing"
+)
+
+func TestXfrmStats(t *testing.T) {
+ xfrmStats, err := FS("fixtures").NewXfrmStat()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, test := range []struct {
+ name string
+ want int
+ got int
+ }{
+ {name: "XfrmInError", want: 1, got: xfrmStats.XfrmInError},
+ {name: "XfrmInBufferError", want: 2, got: xfrmStats.XfrmInBufferError},
+ {name: "XfrmInHdrError", want: 4, got: xfrmStats.XfrmInHdrError},
+ {name: "XfrmInNoStates", want: 3, got: xfrmStats.XfrmInNoStates},
+ {name: "XfrmInStateProtoError", want: 40, got: xfrmStats.XfrmInStateProtoError},
+ {name: "XfrmInStateModeError", want: 100, got: xfrmStats.XfrmInStateModeError},
+ {name: "XfrmInStateSeqError", want: 6000, got: xfrmStats.XfrmInStateSeqError},
+ {name: "XfrmInStateExpired", want: 4, got: xfrmStats.XfrmInStateExpired},
+ {name: "XfrmInStateMismatch", want: 23451, got: xfrmStats.XfrmInStateMismatch},
+ {name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid},
+ {name: "XfrmInTmplMismatch", want: 51, got: xfrmStats.XfrmInTmplMismatch},
+ {name: "XfrmInNoPols", want: 65432, got: xfrmStats.XfrmInNoPols},
+ {name: "XfrmInPolBlock", want: 100, got: xfrmStats.XfrmInPolBlock},
+ {name: "XfrmInPolError", want: 10000, got: xfrmStats.XfrmInPolError},
+ {name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError},
+ {name: "XfrmOutBundleGenError", want: 43321, got: xfrmStats.XfrmOutBundleGenError},
+ {name: "XfrmOutBundleCheckError", want: 555, got: xfrmStats.XfrmOutBundleCheckError},
+ {name: "XfrmOutNoStates", want: 869, got: xfrmStats.XfrmOutNoStates},
+ {name: "XfrmOutStateProtoError", want: 4542, got: xfrmStats.XfrmOutStateProtoError},
+ {name: "XfrmOutStateModeError", want: 4, got: xfrmStats.XfrmOutStateModeError},
+ {name: "XfrmOutStateSeqError", want: 543, got: xfrmStats.XfrmOutStateSeqError},
+ {name: "XfrmOutStateExpired", want: 565, got: xfrmStats.XfrmOutStateExpired},
+ {name: "XfrmOutPolBlock", want: 43456, got: xfrmStats.XfrmOutPolBlock},
+ {name: "XfrmOutPolDead", want: 7656, got: xfrmStats.XfrmOutPolDead},
+ {name: "XfrmOutPolError", want: 1454, got: xfrmStats.XfrmOutPolError},
+ {name: "XfrmFwdHdrError", want: 6654, got: xfrmStats.XfrmFwdHdrError},
+ {name: "XfrmOutStateInvaliad", want: 28765, got: xfrmStats.XfrmOutStateInvalid},
+ {name: "XfrmAcquireError", want: 24532, got: xfrmStats.XfrmAcquireError},
+ {name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid},
+ {name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError},
+ } {
+ if test.want != test.got {
+ t.Errorf("Want %s %d, have %d", test.name, test.want, test.got)
+ }
+ }
+}