diff -Nru golang-procfs-0+git20180613.7d6f385/.circleci/config.yml golang-procfs-0+git20181204.1dc9a6c/.circleci/config.yml --- golang-procfs-0+git20180613.7d6f385/.circleci/config.yml 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/.circleci/config.yml 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1,47 @@ +--- +version: 2.1 + +commands: + linux: + steps: + - run: make style check_license vet test staticcheck + windows: + steps: + - run: make style check_license vet staticcheck + +jobs: + test: + parameters: + go_version: + type: string + os: + type: string + docker: + - image: circleci/golang:<< parameters.go_version >> + environment: + GOOS: "<< parameters.os >>" + working_directory: /go/src/github.com/prometheus/procfs + steps: + - checkout + - << parameters.os >> + +workflows: + version: 2 + procfs: + jobs: + - test: + name: linux-1-10 + os: linux + go_version: "1.10" + - test: + name: linux-1-11 + os: linux + go_version: "1.11" + - test: + name: windows-1-10 + os: windows + go_version: "1.10" + - test: + name: windows-1-11 + os: windows + go_version: "1.11" diff -Nru golang-procfs-0+git20180613.7d6f385/debian/changelog golang-procfs-0+git20181204.1dc9a6c/debian/changelog --- golang-procfs-0+git20180613.7d6f385/debian/changelog 2018-06-13 14:32:29.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/debian/changelog 2018-12-13 23:22:53.000000000 +0000 @@ -1,3 +1,11 @@ +golang-procfs (0+git20181204.1dc9a6c-1) unstable; urgency=medium + + * debian/copyright: Add missing ttar attribution. + * New upstream snapshot. + * Update Standards-Version with no changes. + + -- Martín Ferrari Thu, 13 Dec 2018 23:22:53 +0000 + golang-procfs (0+git20180613.7d6f385-1) unstable; urgency=medium [ Martín Ferrari ] diff -Nru golang-procfs-0+git20180613.7d6f385/debian/control golang-procfs-0+git20181204.1dc9a6c/debian/control --- golang-procfs-0+git20180613.7d6f385/debian/control 2018-06-13 14:32:29.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/debian/control 2018-12-13 23:22:53.000000000 +0000 @@ -7,7 +7,7 @@ Build-Depends: debhelper (>= 11), dh-golang (>= 1.17), golang-any, -Standards-Version: 4.1.4 +Standards-Version: 4.2.1 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-procfs Vcs-Git: https://salsa.debian.org/go-team/packages/golang-procfs.git Homepage: https://github.com/prometheus/procfs.git diff -Nru golang-procfs-0+git20180613.7d6f385/debian/copyright golang-procfs-0+git20181204.1dc9a6c/debian/copyright --- golang-procfs-0+git20180613.7d6f385/debian/copyright 2018-06-13 14:32:29.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/debian/copyright 2018-12-13 23:22:53.000000000 +0000 @@ -6,6 +6,10 @@ Copyright: 2014-2015 The Prometheus Authors License: Apache-2.0 +Files: ttar +Copyright: 2017 Roger Luethi +License: Apache-2.0 + Files: debian/* Copyright: 2015 Martín Ferrari License: Apache-2.0 diff -Nru golang-procfs-0+git20180613.7d6f385/fixtures.ttar golang-procfs-0+git20181204.1dc9a6c/fixtures.ttar --- golang-procfs-0+git20180613.7d6f385/fixtures.ttar 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/fixtures.ttar 2018-12-04 21:11:12.000000000 +0000 @@ -15,6 +15,9 @@ vim Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/26231/cwd +SymlinkTo: /usr/bin +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/26231/exe SymlinkTo: /usr/bin/vim # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -111,6 +114,9 @@ Path: fixtures/26231/ns/net SymlinkTo: net:[4026531993] # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/26231/root +SymlinkTo: / +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/26231/stat Lines: 1 26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0 @@ -128,6 +134,9 @@ ata_sff Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/26232/cwd +SymlinkTo: /does/not/exist +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/26232/fd Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -167,6 +176,9 @@ Max realtime timeout unlimited unlimited us Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/26232/root +SymlinkTo: /does/not/exist +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/26232/stat Lines: 1 33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 @@ -444,3 +456,7 @@ Lines: 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/.unpacked +Lines: 0 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru golang-procfs-0+git20180613.7d6f385/go.mod golang-procfs-0+git20181204.1dc9a6c/go.mod --- golang-procfs-0+git20180613.7d6f385/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/go.mod 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1 @@ +module github.com/prometheus/procfs diff -Nru golang-procfs-0+git20180613.7d6f385/internal/util/parse.go golang-procfs-0+git20181204.1dc9a6c/internal/util/parse.go --- golang-procfs-0+git20180613.7d6f385/internal/util/parse.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/internal/util/parse.go 2018-12-04 21:11:12.000000000 +0000 @@ -13,7 +13,11 @@ package util -import "strconv" +import ( + "io/ioutil" + "strconv" + "strings" +) // ParseUint32s parses a slice of strings into a slice of uint32s. func ParseUint32s(ss []string) ([]uint32, error) { @@ -44,3 +48,12 @@ return us, nil } + +// ReadUintFromFile reads a file and attempts to parse a uint64 from it. +func ReadUintFromFile(path string) (uint64, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return 0, err + } + return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) +} diff -Nru golang-procfs-0+git20180613.7d6f385/internal/util/sysreadfile_linux.go golang-procfs-0+git20181204.1dc9a6c/internal/util/sysreadfile_linux.go --- golang-procfs-0+git20180613.7d6f385/internal/util/sysreadfile_linux.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/internal/util/sysreadfile_linux.go 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1,45 @@ +// Copyright 2018 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. + +// +build !windows + +package util + +import ( + "bytes" + "os" + "syscall" +) + +// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly. +// https://github.com/prometheus/node_exporter/pull/728/files +func SysReadFile(file string) (string, error) { + f, err := os.Open(file) + if err != nil { + return "", err + } + defer f.Close() + + // On some machines, hwmon drivers are broken and return EAGAIN. This causes + // Go's ioutil.ReadFile implementation to poll forever. + // + // Since we either want to read data or bail immediately, do the simplest + // possible read using syscall directly. + b := make([]byte, 128) + n, err := syscall.Read(int(f.Fd()), b) + if err != nil { + return "", err + } + + return string(bytes.TrimSpace(b[:n])), nil +} diff -Nru golang-procfs-0+git20180613.7d6f385/Makefile golang-procfs-0+git20181204.1dc9a6c/Makefile --- golang-procfs-0+git20180613.7d6f385/Makefile 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/Makefile 2018-12-04 21:11:12.000000000 +0000 @@ -11,49 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Ensure GOBIN is not set during build so that promu is installed to the correct path -unexport GOBIN - -GO ?= go -GOFMT ?= $(GO)fmt -FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) -STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck -pkgs = $(shell $(GO) list ./... | grep -v /vendor/) - -PREFIX ?= $(shell pwd) -BIN_DIR ?= $(shell pwd) - -ifdef DEBUG - bindata_flags = -debug -endif - -STATICCHECK_IGNORE = - -all: format staticcheck build test - -style: - @echo ">> checking code style" - @! $(GOFMT) -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^' - -check_license: - @echo ">> checking license header" - @./scripts/check_license.sh - -test: fixtures/.unpacked sysfs/fixtures/.unpacked - @echo ">> running all tests" - @$(GO) test -race $(shell $(GO) list ./... | grep -v /vendor/ | grep -v examples) - -format: - @echo ">> formatting code" - @$(GO) fmt $(pkgs) - -vet: - @echo ">> vetting code" - @$(GO) vet $(pkgs) - -staticcheck: $(STATICCHECK) - @echo ">> running staticcheck" - @$(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) +include Makefile.common %/.unpacked: %.ttar ./ttar -C $(dir $*) -x -f $*.ttar @@ -65,13 +23,8 @@ rm -v $(dir $*)fixtures/.unpacked ./ttar -C $(dir $*) -c -f $*fixtures.ttar fixtures/ -$(FIRST_GOPATH)/bin/staticcheck: - @GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck - -.PHONY: all style check_license format test vet staticcheck +.PHONY: build +build: -# Declaring the binaries at their default locations as PHONY targets is a hack -# to ensure the latest version is downloaded on every make execution. -# If this is not desired, copy/symlink these binaries to a different path and -# set the respective environment variables. -.PHONY: $(GOPATH)/bin/staticcheck +.PHONY: test +test: fixtures/.unpacked sysfs/fixtures/.unpacked common-test diff -Nru golang-procfs-0+git20180613.7d6f385/Makefile.common golang-procfs-0+git20181204.1dc9a6c/Makefile.common --- golang-procfs-0+git20180613.7d6f385/Makefile.common 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/Makefile.common 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1,223 @@ +# Copyright 2018 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. + + +# A common Makefile that includes rules to be reused in different prometheus projects. +# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! + +# Example usage : +# Create the main Makefile in the root project directory. +# include Makefile.common +# customTarget: +# @echo ">> Running customTarget" +# + +# Ensure GOBIN is not set during build so that promu is installed to the correct path +unexport GOBIN + +GO ?= go +GOFMT ?= $(GO)fmt +FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) +GOOPTS ?= + +GO_VERSION ?= $(shell $(GO) version) +GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) +PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') + +unexport GOVENDOR +ifeq (, $(PRE_GO_111)) + ifneq (,$(wildcard go.mod)) + # Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). + GO111MODULE := on + + ifneq (,$(wildcard vendor)) + # Always use the local vendor/ directory to satisfy the dependencies. + GOOPTS := $(GOOPTS) -mod=vendor + endif + endif +else + ifneq (,$(wildcard go.mod)) + ifneq (,$(wildcard vendor)) +$(warning This repository requires Go >= 1.11 because of Go modules) +$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') + endif + else + # This repository isn't using Go modules (yet). + GOVENDOR := $(FIRST_GOPATH)/bin/govendor + endif + + unexport GO111MODULE +endif +PROMU := $(FIRST_GOPATH)/bin/promu +STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck +pkgs = ./... + +GO_VERSION ?= $(shell $(GO) version) +GO_BUILD_PLATFORM ?= $(subst /,-,$(lastword $(GO_VERSION))) + +PROMU_VERSION ?= 0.2.0 +PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz + +PREFIX ?= $(shell pwd) +BIN_DIR ?= $(shell pwd) +DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) +DOCKER_REPO ?= prom + +.PHONY: all +all: precheck style staticcheck unused build test + +# This rule is used to forward a target like "build" to "common-build". This +# allows a new "build" target to be defined in a Makefile which includes this +# one and override "common-build" without override warnings. +%: common-% ; + +.PHONY: common-style +common-style: + @echo ">> checking code style" + @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \ + if [ -n "$${fmtRes}" ]; then \ + echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ + echo "Please ensure you are using $$($(GO) version) for formatting code."; \ + exit 1; \ + fi + +.PHONY: common-check_license +common-check_license: + @echo ">> checking license header" + @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \ + awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ + done); \ + if [ -n "$${licRes}" ]; then \ + echo "license header checking failed:"; echo "$${licRes}"; \ + exit 1; \ + fi + +.PHONY: common-test-short +common-test-short: + @echo ">> running short tests" + GO111MODULE=$(GO111MODULE) $(GO) test -short $(GOOPTS) $(pkgs) + +.PHONY: common-test +common-test: + @echo ">> running all tests" + GO111MODULE=$(GO111MODULE) $(GO) test -race $(GOOPTS) $(pkgs) + +.PHONY: common-format +common-format: + @echo ">> formatting code" + GO111MODULE=$(GO111MODULE) $(GO) fmt $(GOOPTS) $(pkgs) + +.PHONY: common-vet +common-vet: + @echo ">> vetting code" + GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) + +.PHONY: common-staticcheck +common-staticcheck: $(STATICCHECK) + @echo ">> running staticcheck" +ifdef GO111MODULE + GO111MODULE=$(GO111MODULE) $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" -checks "SA*" $(pkgs) +else + $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) +endif + +.PHONY: common-unused +common-unused: $(GOVENDOR) +ifdef GOVENDOR + @echo ">> running check for unused packages" + @$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' +else +ifdef GO111MODULE + @echo ">> running check for unused/missing packages in go.mod" + GO111MODULE=$(GO111MODULE) $(GO) mod tidy + @git diff --exit-code -- go.sum go.mod +ifneq (,$(wildcard vendor)) + @echo ">> running check for unused packages in vendor/" + GO111MODULE=$(GO111MODULE) $(GO) mod vendor + @git diff --exit-code -- go.sum go.mod vendor/ +endif +endif +endif + +.PHONY: common-build +common-build: promu + @echo ">> building binaries" + GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) + +.PHONY: common-tarball +common-tarball: promu + @echo ">> building release tarball" + $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) + +.PHONY: common-docker +common-docker: + docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" . + +.PHONY: common-docker-publish +common-docker-publish: + docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)" + +.PHONY: common-docker-tag-latest +common-docker-tag-latest: + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):latest" + +.PHONY: promu +promu: $(PROMU) + +$(PROMU): + curl -s -L $(PROMU_URL) | tar -xvz -C /tmp + mkdir -v -p $(FIRST_GOPATH)/bin + cp -v /tmp/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(PROMU) + +.PHONY: proto +proto: + @echo ">> generating code from proto files" + @./scripts/genproto.sh + +.PHONY: $(STATICCHECK) +$(STATICCHECK): +ifdef GO111MODULE +# Get staticcheck from a temporary directory to avoid modifying the local go.{mod,sum}. +# See https://github.com/golang/go/issues/27643. +# For now, we are using the next branch of staticcheck because master isn't compatible yet with Go modules. + tmpModule=$$(mktemp -d 2>&1) && \ + mkdir -p $${tmpModule}/staticcheck && \ + cd "$${tmpModule}"/staticcheck && \ + GO111MODULE=on $(GO) mod init example.com/staticcheck && \ + GO111MODULE=on GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck@next && \ + rm -rf $${tmpModule}; +else + GOOS= GOARCH= GO111MODULE=off $(GO) get -u honnef.co/go/tools/cmd/staticcheck +endif + +ifdef GOVENDOR +.PHONY: $(GOVENDOR) +$(GOVENDOR): + GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor +endif + +.PHONY: precheck +precheck:: + +define PRECHECK_COMMAND_template = +precheck:: $(1)_precheck + + +PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) +.PHONY: $(1)_precheck +$(1)_precheck: + @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ + echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ + exit 1; \ + fi +endef diff -Nru golang-procfs-0+git20180613.7d6f385/mountstats.go golang-procfs-0+git20181204.1dc9a6c/mountstats.go --- golang-procfs-0+git20180613.7d6f385/mountstats.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/mountstats.go 2018-12-04 21:11:12.000000000 +0000 @@ -39,8 +39,11 @@ statVersion10 = "1.0" statVersion11 = "1.1" - fieldTransport10Len = 10 - fieldTransport11Len = 13 + fieldTransport10TCPLen = 10 + fieldTransport10UDPLen = 7 + + fieldTransport11TCPLen = 13 + fieldTransport11UDPLen = 10 ) // A Mount is a device mount parsed from /proc/[pid]/mountstats. @@ -186,6 +189,8 @@ // A NFSTransportStats contains statistics for the NFS mount RPC requests and // responses. type NFSTransportStats struct { + // The transport protocol used for the NFS mount. + Protocol string // The local port used for the NFS mount. Port uint64 // Number of times the client has had to establish a connection from scratch @@ -360,7 +365,7 @@ return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss) } - tstats, err := parseNFSTransportStats(ss[2:], statVersion) + tstats, err := parseNFSTransportStats(ss[1:], statVersion) if err != nil { return nil, err } @@ -522,13 +527,33 @@ // parseNFSTransportStats parses a NFSTransportStats line using an input set of // integer fields matched to a specific stats version. func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) { + // Extract the protocol field. It is the only string value in the line + protocol := ss[0] + ss = ss[1:] + switch statVersion { case statVersion10: - if len(ss) != fieldTransport10Len { + var expectedLength int + if protocol == "tcp" { + expectedLength = fieldTransport10TCPLen + } else if protocol == "udp" { + expectedLength = fieldTransport10UDPLen + } else { + return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.0 statement: %v", protocol, ss) + } + if len(ss) != expectedLength { return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss) } case statVersion11: - if len(ss) != fieldTransport11Len { + var expectedLength int + if protocol == "tcp" { + expectedLength = fieldTransport11TCPLen + } else if protocol == "udp" { + expectedLength = fieldTransport11UDPLen + } else { + return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.1 statement: %v", protocol, ss) + } + if len(ss) != expectedLength { return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss) } default: @@ -536,12 +561,13 @@ } // Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay - // in a v1.0 response. + // in a v1.0 response. Since the stat length is bigger for TCP stats, we use + // the TCP length here. // // Note: slice length must be set to length of v1.1 stats to avoid a panic when // only v1.0 stats are present. // See: https://github.com/prometheus/node_exporter/issues/571. - ns := make([]uint64, fieldTransport11Len) + ns := make([]uint64, fieldTransport11TCPLen) for i, s := range ss { n, err := strconv.ParseUint(s, 10, 64) if err != nil { @@ -551,7 +577,18 @@ ns[i] = n } + // The fields differ depending on the transport protocol (TCP or UDP) + // From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt + // + // For the udp RPC transport there is no connection count, connect idle time, + // or idle time (fields #3, #4, and #5); all other fields are the same. So + // we set them to 0 here. + if protocol == "udp" { + ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...) + } + return &NFSTransportStats{ + Protocol: protocol, Port: ns[0], Bind: ns[1], Connect: ns[2], diff -Nru golang-procfs-0+git20180613.7d6f385/mountstats_test.go golang-procfs-0+git20181204.1dc9a6c/mountstats_test.go --- golang-procfs-0+git20180613.7d6f385/mountstats_test.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/mountstats_test.go 2018-12-04 21:11:12.000000000 +0000 @@ -103,7 +103,12 @@ invalid: true, }, { - name: "NFSv3 device with transport stats version 1.0 OK", + name: "NFSv3 device with bad transport protocol", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nxprt: tcpx 0 0 0 0 0 0 0 0 0 0", + invalid: true, + }, + { + name: "NFSv3 device using TCP with transport stats version 1.0 OK", s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.0\nxprt: tcp 1 2 3 4 5 6 7 8 9 10", mounts: []*Mount{{ Device: "192.168.1.1:/srv", @@ -112,6 +117,7 @@ Stats: &MountStatsNFS{ StatVersion: "1.0", Transport: NFSTransportStats{ + Protocol: "tcp", Port: 1, Bind: 2, Connect: 3, @@ -122,6 +128,93 @@ BadTransactionIDs: 8, CumulativeActiveRequests: 9, CumulativeBacklog: 10, + MaximumRPCSlotsUsed: 0, // these three are not + CumulativeSendingQueue: 0, // present in statvers=1.0 + CumulativePendingQueue: 0, // + }, + }, + }}, + }, + { + name: "NFSv3 device using UDP with transport stats version 1.0 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.0\nxprt: udp 1 2 3 4 5 6 7", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.0", + Transport: NFSTransportStats{ + Protocol: "udp", + Port: 1, + Bind: 2, + Connect: 0, + ConnectIdleTime: 0, + IdleTime: 0, + Sends: 3, + Receives: 4, + BadTransactionIDs: 5, + CumulativeActiveRequests: 6, + CumulativeBacklog: 7, + MaximumRPCSlotsUsed: 0, // these three are not + CumulativeSendingQueue: 0, // present in statvers=1.0 + CumulativePendingQueue: 0, // + }, + }, + }}, + }, + { + name: "NFSv3 device using TCP with transport stats version 1.1 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.1\nxprt: tcp 1 2 3 4 5 6 7 8 9 10 11 12 13", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + Transport: NFSTransportStats{ + Protocol: "tcp", + Port: 1, + Bind: 2, + Connect: 3, + ConnectIdleTime: 4, + IdleTime: 5 * time.Second, + Sends: 6, + Receives: 7, + BadTransactionIDs: 8, + CumulativeActiveRequests: 9, + CumulativeBacklog: 10, + MaximumRPCSlotsUsed: 11, + CumulativeSendingQueue: 12, + CumulativePendingQueue: 13, + }, + }, + }}, + }, + { + name: "NFSv3 device using UDP with transport stats version 1.1 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.1\nxprt: udp 1 2 3 4 5 6 7 8 9 10", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + Transport: NFSTransportStats{ + Protocol: "udp", + Port: 1, + Bind: 2, + Connect: 0, // these three are not + ConnectIdleTime: 0, // present for UDP + IdleTime: 0, // + Sends: 3, + Receives: 4, + BadTransactionIDs: 5, + CumulativeActiveRequests: 6, + CumulativeBacklog: 7, + MaximumRPCSlotsUsed: 8, + CumulativeSendingQueue: 9, + CumulativePendingQueue: 10, }, }, }}, @@ -212,6 +305,7 @@ }, }, Transport: NFSTransportStats{ + Protocol: "tcp", Port: 832, Connect: 1, IdleTime: 11 * time.Second, diff -Nru golang-procfs-0+git20180613.7d6f385/proc.go golang-procfs-0+git20181204.1dc9a6c/proc.go --- golang-procfs-0+git20180613.7d6f385/proc.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/proc.go 2018-12-04 21:11:12.000000000 +0000 @@ -156,6 +156,26 @@ return exe, err } +// Cwd returns the absolute path to the current working directory of the process. +func (p Proc) Cwd() (string, error) { + wd, err := os.Readlink(p.path("cwd")) + if os.IsNotExist(err) { + return "", nil + } + + return wd, err +} + +// RootDir returns the absolute path to the process's root directory (as set by chroot) +func (p Proc) RootDir() (string, error) { + rdir, err := os.Readlink(p.path("root")) + if os.IsNotExist(err) { + return "", nil + } + + return rdir, err +} + // FileDescriptors returns the currently open file descriptors of a process. func (p Proc) FileDescriptors() ([]uintptr, error) { names, err := p.fileDescriptors() diff -Nru golang-procfs-0+git20180613.7d6f385/proc_test.go golang-procfs-0+git20181204.1dc9a6c/proc_test.go --- golang-procfs-0+git20180613.7d6f385/proc_test.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/proc_test.go 2018-12-04 21:11:12.000000000 +0000 @@ -111,7 +111,63 @@ t.Fatal(err) } if !reflect.DeepEqual(tt.want, exe) { - t.Errorf("want absolute path to cmdline %v, have %v", tt.want, exe) + t.Errorf("want absolute path to exe %v, have %v", tt.want, exe) + } + } +} + +func TestCwd(t *testing.T) { + for _, tt := range []struct { + process int + want string + brokenLink bool + }{ + {process: 26231, want: "/usr/bin"}, + {process: 26232, want: "/does/not/exist", brokenLink: true}, + {process: 26233, want: ""}, + } { + p, err := FS("fixtures").NewProc(tt.process) + if err != nil { + t.Fatal(err) + } + wd, err := p.Cwd() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, wd) { + if wd == "" && tt.brokenLink { + // Allow the result to be empty when can't os.Readlink broken links + continue + } + t.Errorf("want absolute path to cwd %v, have %v", tt.want, wd) + } + } +} + +func TestRoot(t *testing.T) { + for _, tt := range []struct { + process int + want string + brokenLink bool + }{ + {process: 26231, want: "/"}, + {process: 26232, want: "/does/not/exist", brokenLink: true}, + {process: 26233, want: ""}, + } { + p, err := FS("fixtures").NewProc(tt.process) + if err != nil { + t.Fatal(err) + } + rdir, err := p.RootDir() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, rdir) { + if rdir == "" && tt.brokenLink { + // Allow the result to be empty when can't os.Readlink broken links + continue + } + t.Errorf("want absolute path to rootdir %v, have %v", tt.want, rdir) } } } diff -Nru golang-procfs-0+git20180613.7d6f385/sysfs/fixtures.ttar golang-procfs-0+git20181204.1dc9a6c/sysfs/fixtures.ttar --- golang-procfs-0+git20180613.7d6f385/sysfs/fixtures.ttar 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/sysfs/fixtures.ttar 2018-12-04 21:11:12.000000000 +0000 @@ -389,6 +389,148 @@ 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpu0 +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu0/cpufreq +SymlinkTo: ../cpufreq/policy0 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpu1 +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpu1/cpufreq +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq +Lines: 1 +1200195 +Mode: 400 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq +Lines: 1 +3300000 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq +Lines: 1 +1200000 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/cpuinfo_transition_latency +Lines: 1 +4294967295 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/related_cpus +Lines: 1 +1 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_available_governors +Lines: 1 +performance powersave +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_driver +Lines: 1 +intel_pstate +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_governor +Lines: 1 +powersave +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_max_freq +Lines: 1 +3300000 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_min_freq +Lines: 1 +1200000 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpu1/cpufreq/scaling_setspeed +Lines: 1 + +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpufreq +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpufreq/policy0 +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/affected_cpus +Lines: 1 +0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq +Lines: 1 +2400000 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq +Lines: 1 +800000 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/cpuinfo_transition_latency +Lines: 1 +0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/related_cpus +Lines: 1 +0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_available_governors +Lines: 1 +performance powersave +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_cur_freq +Lines: 1 +1219917 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_driver +Lines: 1 +intel_pstate +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_governor +Lines: 1 +powersave +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_max_freq +Lines: 1 +2400000 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_min_freq +Lines: 1 +800000 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/devices/system/cpu/cpufreq/policy0/scaling_setspeed +Lines: 1 + +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/devices/system/cpu/cpufreq/policy1 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/fs Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru golang-procfs-0+git20180613.7d6f385/sysfs/net_class.go golang-procfs-0+git20181204.1dc9a6c/sysfs/net_class.go --- golang-procfs-0+git20180613.7d6f385/sysfs/net_class.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/sysfs/net_class.go 2018-12-04 21:11:12.000000000 +0000 @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build !windows + package sysfs import ( @@ -20,7 +22,8 @@ "reflect" "strconv" "strings" - "syscall" + + "github.com/prometheus/procfs/internal/util" ) // NetClassIface contains info from files in /sys/class/net/ @@ -109,7 +112,7 @@ panic(fmt.Errorf("field %s does not have a filename tag", fieldType.Name)) } - fileContents, err := sysReadFile(devicePath + "/" + fieldType.Tag.Get("fileName")) + value, err := util.SysReadFile(devicePath + "/" + fieldType.Tag.Get("fileName")) if err != nil { if os.IsNotExist(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" { @@ -117,7 +120,6 @@ } return nil, fmt.Errorf("could not access file %s: %s", fieldType.Tag.Get("fileName"), err) } - value := strings.TrimSpace(string(fileContents)) switch fieldValue.Kind() { case reflect.String: @@ -149,26 +151,3 @@ return &interfaceClass, nil } - -// sysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly. -// https://github.com/prometheus/node_exporter/pull/728/files -func sysReadFile(file string) ([]byte, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - - // On some machines, hwmon drivers are broken and return EAGAIN. This causes - // Go's ioutil.ReadFile implementation to poll forever. - // - // Since we either want to read data or bail immediately, do the simplest - // possible read using syscall directly. - b := make([]byte, 128) - n, err := syscall.Read(int(f.Fd()), b) - if err != nil { - return nil, err - } - - return b[:n], nil -} diff -Nru golang-procfs-0+git20180613.7d6f385/sysfs/net_class_test.go golang-procfs-0+git20181204.1dc9a6c/sysfs/net_class_test.go --- golang-procfs-0+git20180613.7d6f385/sysfs/net_class_test.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/sysfs/net_class_test.go 2018-12-04 21:11:12.000000000 +0000 @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build !windows + package sysfs import ( diff -Nru golang-procfs-0+git20180613.7d6f385/sysfs/system_cpu.go golang-procfs-0+git20181204.1dc9a6c/sysfs/system_cpu.go --- golang-procfs-0+git20180613.7d6f385/sysfs/system_cpu.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/sysfs/system_cpu.go 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1,141 @@ +// Copyright 2018 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. + +// +build !windows + +package sysfs + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// SystemCPUCpufreqStats contains stats from devices/system/cpu/cpu[0-9]*/cpufreq/... +type SystemCPUCpufreqStats struct { + Name string + CurrentFrequency uint64 + MinimumFrequency uint64 + MaximumFrequency uint64 + TransitionLatency uint64 + AvailableGovernors string + Driver string + Govenor string + RelatedCpus string + SetSpeed string +} + +// TODO: Add topology support. + +// TODO: Add thermal_throttle support. + +// NewSystemCpufreq returns CPU frequency metrics for all CPUs. +func NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return []SystemCPUCpufreqStats{}, err + } + + return fs.NewSystemCpufreq() +} + +// NewSystemCpufreq returns CPU frequency metrics for all CPUs. +func (fs FS) NewSystemCpufreq() ([]SystemCPUCpufreqStats, error) { + var cpufreq = &SystemCPUCpufreqStats{} + + cpus, err := filepath.Glob(fs.Path("devices/system/cpu/cpu[0-9]*")) + if err != nil { + return []SystemCPUCpufreqStats{}, err + } + + systemCpufreq := []SystemCPUCpufreqStats{} + for _, cpu := range cpus { + cpuName := filepath.Base(cpu) + cpuNum := strings.TrimPrefix(cpuName, "cpu") + + cpuCpufreqPath := filepath.Join(cpu, "cpufreq") + if _, err := os.Stat(cpuCpufreqPath); os.IsNotExist(err) { + continue + } + if err != nil { + return []SystemCPUCpufreqStats{}, err + } + + if _, err = os.Stat(filepath.Join(cpuCpufreqPath, "scaling_cur_freq")); err == nil { + cpufreq, err = parseCpufreqCpuinfo("scaling", cpuCpufreqPath) + } else if _, err = os.Stat(filepath.Join(cpuCpufreqPath, "cpuinfo_cur_freq")); err == nil { + // Older kernels have metrics named `cpuinfo_...`. + cpufreq, err = parseCpufreqCpuinfo("cpuinfo", cpuCpufreqPath) + } else { + return []SystemCPUCpufreqStats{}, fmt.Errorf("CPU %v is missing cpufreq", cpu) + } + if err != nil { + return []SystemCPUCpufreqStats{}, err + } + cpufreq.Name = cpuNum + systemCpufreq = append(systemCpufreq, *cpufreq) + } + + return systemCpufreq, nil +} + +func parseCpufreqCpuinfo(prefix string, cpuPath string) (*SystemCPUCpufreqStats, error) { + uintFiles := []string{ + prefix + "_cur_freq", + prefix + "_max_freq", + prefix + "_min_freq", + "cpuinfo_transition_latency", + } + uintOut := make([]uint64, len(uintFiles)) + + for i, f := range uintFiles { + v, err := util.ReadUintFromFile(filepath.Join(cpuPath, f)) + if err != nil { + return &SystemCPUCpufreqStats{}, err + } + + uintOut[i] = v + } + + stringFiles := []string{ + "scaling_available_governors", + "scaling_driver", + "scaling_governor", + "related_cpus", + "scaling_setspeed", + } + stringOut := make([]string, len(stringFiles)) + var err error + + for i, f := range stringFiles { + stringOut[i], err = util.SysReadFile(filepath.Join(cpuPath, f)) + if err != nil { + return &SystemCPUCpufreqStats{}, err + } + } + + return &SystemCPUCpufreqStats{ + CurrentFrequency: uintOut[0], + MaximumFrequency: uintOut[1], + MinimumFrequency: uintOut[2], + TransitionLatency: uintOut[3], + AvailableGovernors: stringOut[0], + Driver: stringOut[1], + Govenor: stringOut[2], + RelatedCpus: stringOut[3], + SetSpeed: stringOut[4], + }, nil +} diff -Nru golang-procfs-0+git20180613.7d6f385/sysfs/system_cpu_test.go golang-procfs-0+git20181204.1dc9a6c/sysfs/system_cpu_test.go --- golang-procfs-0+git20180613.7d6f385/sysfs/system_cpu_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/sysfs/system_cpu_test.go 2018-12-04 21:11:12.000000000 +0000 @@ -0,0 +1,66 @@ +// Copyright 2018 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. + +// +build !windows + +package sysfs + +import ( + "reflect" + "testing" +) + +func TestNewSystemCpufreq(t *testing.T) { + fs, err := NewFS("fixtures") + if err != nil { + t.Fatal(err) + } + + c, err := fs.NewSystemCpufreq() + if err != nil { + t.Fatal(err) + } + + systemCpufreq := []SystemCPUCpufreqStats{ + // Ubuntu 16.04 (4.15.0-20-generic), has `scaling_cur_freq` file. + { + Name: "0", + CurrentFrequency: 1219917, + MinimumFrequency: 800000, + MaximumFrequency: 2400000, + TransitionLatency: 0, + AvailableGovernors: "performance powersave", + Driver: "intel_pstate", + Govenor: "powersave", + RelatedCpus: "0", + SetSpeed: "", + }, + // RHEL 7.3 (3.10.0-514.26.2.el7), missing `scaling_cur_freq` file. + { + Name: "1", + CurrentFrequency: 1200195, + MinimumFrequency: 1200000, + MaximumFrequency: 3300000, + TransitionLatency: 4294967295, + AvailableGovernors: "performance powersave", + Driver: "intel_pstate", + Govenor: "powersave", + RelatedCpus: "1", + SetSpeed: "", + }, + } + + if !reflect.DeepEqual(systemCpufreq, c) { + t.Errorf("Result not correct: want %v, have %v", systemCpufreq, c) + } +} diff -Nru golang-procfs-0+git20180613.7d6f385/.travis.yml golang-procfs-0+git20181204.1dc9a6c/.travis.yml --- golang-procfs-0+git20180613.7d6f385/.travis.yml 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -sudo: false - -language: go - -go: -- 1.7.x -- 1.8.x -- 1.9.x -- 1.10.x -- 1.x - -go_import_path: github.com/prometheus/procfs - -script: -- make style check_license vet test staticcheck diff -Nru golang-procfs-0+git20180613.7d6f385/xfrm.go golang-procfs-0+git20181204.1dc9a6c/xfrm.go --- golang-procfs-0+git20180613.7d6f385/xfrm.go 2018-06-12 22:21:13.000000000 +0000 +++ golang-procfs-0+git20181204.1dc9a6c/xfrm.go 2018-12-04 21:11:12.000000000 +0000 @@ -113,7 +113,7 @@ if len(fields) != 2 { return XfrmStat{}, fmt.Errorf( - "couldnt parse %s line %s", file.Name(), s.Text()) + "couldn't parse %s line %s", file.Name(), s.Text()) } name := fields[0]