Skip to content

Commit

Permalink
Merge pull request #8 from treydock/tests
Browse files Browse the repository at this point in the history
Improved tests
  • Loading branch information
treydock authored Feb 24, 2020
2 parents 2e017ab + 7777bfb commit 04dba98
Show file tree
Hide file tree
Showing 19 changed files with 518 additions and 121 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ include Makefile.common
DOCKER_IMAGE_NAME ?= gpfs_exporter

coverage:
go test -race -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic ./...
go test -race -coverprofile=coverage.txt -covermode=atomic ./...
4 changes: 2 additions & 2 deletions cmd/gpfs_exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
disableExporterMetrics = kingpin.Flag("web.disable-exporter-metrics", "Exclude metrics about the exporter (promhttp_*, process_*, go_*)").Default("false").Bool()
)

func gpfsHandler() http.HandlerFunc {
func metricsHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
registry := prometheus.NewRegistry()

Expand Down Expand Up @@ -62,7 +62,7 @@ func main() {
log.Infoln("Build context", version.BuildContext())
log.Infof("Starting Server: %s", *listenAddr)

http.Handle("/metrics", gpfsHandler())
http.Handle("/metrics", metricsHandler())
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
//nolint:errcheck
w.Write([]byte(`<html>
Expand Down
77 changes: 77 additions & 0 deletions cmd/gpfs_exporter/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2020 Trey Dockendorf
// 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 main

import (
"fmt"
"github.com/prometheus/common/log"
kingpin "gopkg.in/alecthomas/kingpin.v2"
"io/ioutil"
"net/http"
"os"
"strings"
"testing"
"time"
)

const (
address = "localhost:19303"
)

func TestMain(m *testing.M) {
if _, err := kingpin.CommandLine.Parse([]string{"--no-collector.mmpmon"}); err != nil {
log.Fatal(err)
}
varTrue := true
disableExporterMetrics = &varTrue
go func() {
http.Handle("/metrics", metricsHandler())
log.Fatal(http.ListenAndServe(address, nil))
}()
time.Sleep(1 * time.Second)

exitVal := m.Run()

os.Exit(exitVal)
}

func TestMetricsHandler(t *testing.T) {
_ = log.Base().SetLevel("debug")
body, err := queryExporter()
if err != nil {
t.Fatalf("Unexpected error GET /metrics: %s", err.Error())
}
log.Debugf("body='%s'", body)
if !strings.Contains(body, "gpfs_exporter_collect_error{collector=\"mount\"} 0") {
t.Errorf("Unexpected value for gpfs_exporter_collect_error")
}
}

func queryExporter() (string, error) {
resp, err := http.Get(fmt.Sprintf("http://%s/metrics", address))
if err != nil {
return "", err
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
if err := resp.Body.Close(); err != nil {
return "", err
}
if want, have := http.StatusOK, resp.StatusCode; want != have {
return "", fmt.Errorf("want /metrics status code %d, have %d. Body:\n%s", want, have, b)
}
return string(b), nil
}
74 changes: 0 additions & 74 deletions cmd/gpfs_mmdf_exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,80 +27,6 @@ var (
lockFile = kingpin.Flag("lockfile", "Lock file path").Default("/tmp/gpfs_mmdf_exporter.lock").String()
)

/*
func GetMetrics(fs string) (collector.DFMetric, error) {
out, err := collector.Mmdf(fs)
if err != nil {
return collector.DFMetric{}, err
}
dfMetric, err := collector.Parse_mmdf(out)
if err != nil {
return collector.DFMetric{}, err
}
return dfMetric, nil
}
type Collector struct {
fs string
inodes_used *prometheus.Desc
inodes_free *prometheus.Desc
inodes_allocated *prometheus.Desc
inodes_total *prometheus.Desc
fs_total *prometheus.Desc
fs_free *prometheus.Desc
fs_free_percent *prometheus.Desc
metadata_total *prometheus.Desc
metadata_free *prometheus.Desc
metadata_free_percent *prometheus.Desc
}
func NewCollector(fs string) *Collector {
return &Collector{
fs: fs,
inodes_used: collector.Inodes_used,
inodes_free: collector.Inodes_free,
inodes_allocated: collector.Inodes_allocated,
inodes_total: collector.Inodes_total,
fs_total: collector.Fs_total,
fs_free: collector.Fs_free,
fs_free_percent: collector.Fs_free_percent,
metadata_total: collector.Metadata_total,
metadata_free: collector.Metadata_free,
metadata_free_percent: collector.Metadata_free_percent,
}
}
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.inodes_used
ch <- c.inodes_free
ch <- c.inodes_allocated
ch <- c.inodes_total
ch <- c.fs_total
ch <- c.fs_free
ch <- c.fs_free_percent
ch <- c.metadata_total
ch <- c.metadata_free
ch <- c.metadata_free_percent
}
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
metrics, err := GetMetrics(c.fs)
if err != nil {
log.Fatal(err)
}
ch <- prometheus.MustNewConstMetric(c.inodes_used, prometheus.GaugeValue, float64(metrics.InodesUsed), c.fs)
ch <- prometheus.MustNewConstMetric(c.inodes_free, prometheus.GaugeValue, float64(metrics.InodesFree), c.fs)
ch <- prometheus.MustNewConstMetric(c.inodes_allocated, prometheus.GaugeValue, float64(metrics.InodesAllocated), c.fs)
ch <- prometheus.MustNewConstMetric(c.inodes_total, prometheus.GaugeValue, float64(metrics.InodesTotal), c.fs)
ch <- prometheus.MustNewConstMetric(c.fs_total, prometheus.GaugeValue, float64(metrics.FSTotal), c.fs)
ch <- prometheus.MustNewConstMetric(c.fs_free, prometheus.GaugeValue, float64(metrics.FSFree), c.fs)
ch <- prometheus.MustNewConstMetric(c.fs_free_percent, prometheus.GaugeValue, float64(metrics.FSFreePercent), c.fs)
ch <- prometheus.MustNewConstMetric(c.metadata_total, prometheus.GaugeValue, float64(metrics.MetadataTotal), c.fs)
ch <- prometheus.MustNewConstMetric(c.metadata_free, prometheus.GaugeValue, float64(metrics.MetadataFree), c.fs)
ch <- prometheus.MustNewConstMetric(c.metadata_free_percent, prometheus.GaugeValue, float64(metrics.MetadataFreePercent), c.fs)
}
*/

func collect() {
registry := prometheus.NewRegistry()
registry.MustRegister(collectors.NewMmdfCollector())
Expand Down
32 changes: 32 additions & 0 deletions cmd/gpfs_mmdf_exporter/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020 Trey Dockendorf
// 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 main

import (
"github.com/prometheus/common/log"
kingpin "gopkg.in/alecthomas/kingpin.v2"
"os"
"testing"
)

func TestMain(m *testing.M) {
if _, err := kingpin.CommandLine.Parse([]string{"--output=/dne"}); err != nil {
log.Fatal(err)
}
exitVal := m.Run()
os.Exit(exitVal)
}

func TestCollect(t *testing.T) {
}
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
8 changes: 8 additions & 0 deletions collectors/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package collectors

import (
"fmt"
"github.com/prometheus/client_golang/prometheus"
"os"
"os/exec"
"strconv"
Expand Down Expand Up @@ -48,6 +49,13 @@ func TestExecCommandHelper(t *testing.T) {
os.Exit(i)
}

func setupGatherer(collector Collector) prometheus.Gatherer {
registry := prometheus.NewRegistry()
registry.MustRegister(collector)
gatherers := prometheus.Gatherers{registry}
return gatherers
}

func TestParseMmlsfs(t *testing.T) {
execCommand = fakeExecCommand
mockedStdout = `
Expand Down
38 changes: 37 additions & 1 deletion collectors/mmces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
package collectors

import (
"github.com/prometheus/client_golang/prometheus/testutil"
kingpin "gopkg.in/alecthomas/kingpin.v2"
"os/exec"
"strings"
"testing"
)

func TestParseMmcesStateShow(t *testing.T) {
execCommand = fakeExecCommand
mockedStdout = `
mmcesstate::HEADER:version:reserved:reserved:NODE:AUTH:BLOCK:NETWORK:AUTH_OBJ:NFS:OBJ:SMB:CES:
mmcesstate::0:1:::ib-protocol01.ten.osc.edu:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:HEALTHY:
mmcesstate::0:1:::ib-protocol01.domain:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:HEALTHY:
`
defer func() { execCommand = exec.Command }()
metrics, err := mmces_state_show_parse(mockedStdout)
Expand Down Expand Up @@ -52,3 +55,36 @@ func TestParseMmcesState(t *testing.T) {
t.Errorf("Expected 0 for DEGRADED, got %v", val)
}
}

func TestMMcesCollector(t *testing.T) {
if _, err := kingpin.CommandLine.Parse([]string{"--collector.mmces.nodename=ib-protocol01.domain"}); err != nil {
t.Fatal(err)
}
execCommand = fakeExecCommand
mockedStdout = `
mmcesstate::HEADER:version:reserved:reserved:NODE:AUTH:BLOCK:NETWORK:AUTH_OBJ:NFS:OBJ:SMB:CES:
mmcesstate::0:1:::ib-protocol01.domain:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:DISABLED:HEALTHY:HEALTHY:
`
defer func() { execCommand = exec.Command }()
metadata := `
# HELP gpfs_ces_state GPFS CES health status, 1=healthy 0=not healthy
# TYPE gpfs_ces_state gauge`
expected := `
gpfs_ces_state{service="AUTH",state="HEALTHY"} 1
gpfs_ces_state{service="AUTH_OBJ",state="DISABLED"} 0
gpfs_ces_state{service="BLOCK",state="DISABLED"} 0
gpfs_ces_state{service="CES",state="HEALTHY"} 1
gpfs_ces_state{service="NETWORK",state="HEALTHY"} 1
gpfs_ces_state{service="NFS",state="HEALTHY"} 1
gpfs_ces_state{service="OBJ",state="DISABLED"} 0
gpfs_ces_state{service="SMB",state="HEALTHY"} 1
`
collector := NewMmcesCollector()
gatherers := setupGatherer(collector)
if val := testutil.CollectAndCount(collector); val != 10 {
t.Errorf("Unexpected collection count %d, expected 10", val)
}
if err := testutil.GatherAndCompare(gatherers, strings.NewReader(metadata+expected), "gpfs_ces_state"); err != nil {
t.Errorf("unexpected collecting result:\n%s", err)
}
}
10 changes: 5 additions & 5 deletions collectors/mmdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,16 @@ func NewMmdfCollector() Collector {
InodesAllocated: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "inodes_allocated"),
"GPFS filesystem inodes allocated", []string{"fs"}, nil),
InodesTotal: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "inodes_total"),
"GPFS filesystem inodes total in bytes", []string{"fs"}, nil),
FSTotal: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "total"),
"GPFS filesystem inodes total", []string{"fs"}, nil),
FSTotal: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "total_bytes"),
"GPFS filesystem total size in bytes", []string{"fs"}, nil),
FSFree: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "free"),
FSFree: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "free_bytes"),
"GPFS filesystem free size in bytes", []string{"fs"}, nil),
FSFreePercent: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "free_percent"),
"GPFS filesystem free percent", []string{"fs"}, nil),
MetadataTotal: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "metadata_total"),
MetadataTotal: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "metadata_total_bytes"),
"GPFS total metadata size in bytes", []string{"fs"}, nil),
MetadataFree: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "metadata_free"),
MetadataFree: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "metadata_free_bytes"),
"GPFS metadata free size in bytes", []string{"fs"}, nil),
MetadataFreePercent: prometheus.NewDesc(prometheus.BuildFQName(namespace, "fs", "metadata_free_percent"),
"GPFS metadata free percent", []string{"fs"}, nil),
Expand Down
Loading

0 comments on commit 04dba98

Please sign in to comment.