diff --git a/collector/bonding_test.go b/collector/bonding_test.go index c68a41e7..79b14db7 100644 --- a/collector/bonding_test.go +++ b/collector/bonding_test.go @@ -13,10 +13,10 @@ func TestBonding(t *testing.T) { t.Fatal("bond0 in unexpected state") } - t.Logf("int: %v", bondingStats["int"]) if bondingStats["int"][0] != 2 || bondingStats["int"][1] != 1 { t.Fatal("int in unexpected state") } + if bondingStats["dmz"][0] != 2 || bondingStats["dmz"][1] != 2 { t.Fatal("dmz in unexpected state") } diff --git a/collector/diskstats.go b/collector/diskstats.go index 082ee124..c6c8d6e7 100644 --- a/collector/diskstats.go +++ b/collector/diskstats.go @@ -184,13 +184,17 @@ func getDiskStats() (map[string]map[int]string, error) { if err != nil { return nil, err } + defer file.Close() + return parseDiskStats(file) } -func parseDiskStats(r io.ReadCloser) (map[string]map[int]string, error) { - defer r.Close() - diskStats := map[string]map[int]string{} - scanner := bufio.NewScanner(r) +func parseDiskStats(r io.Reader) (map[string]map[int]string, error) { + var ( + diskStats = map[string]map[int]string{} + scanner = bufio.NewScanner(r) + ) + for scanner.Scan() { parts := strings.Fields(string(scanner.Text())) if len(parts) != len(diskStatsMetrics)+3 { // we strip major, minor and dev @@ -202,5 +206,6 @@ func parseDiskStats(r io.ReadCloser) (map[string]map[int]string, error) { diskStats[dev][i] = v } } + return diskStats, nil } diff --git a/collector/diskstats_test.go b/collector/diskstats_test.go new file mode 100644 index 00000000..a8202944 --- /dev/null +++ b/collector/diskstats_test.go @@ -0,0 +1,27 @@ +package collector + +import ( + "os" + "testing" +) + +func TestDiskStats(t *testing.T) { + file, err := os.Open("fixtures/diskstats") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + diskStats, err := parseDiskStats(file) + if err != nil { + t.Fatal(err) + } + + if want, got := "25353629", diskStats["sda4"][0]; want != got { + t.Errorf("want diskstats sda4 %s, got %s", want, got) + } + + if want, got := "68", diskStats["mmcblk0p2"][10]; want != got { + t.Errorf("want diskstats mmcblk0p2 %s, got %s", want, got) + } +} diff --git a/collector/fixtures/loadavg b/collector/fixtures/loadavg deleted file mode 100644 index 8897b7ce..00000000 --- a/collector/fixtures/loadavg +++ /dev/null @@ -1 +0,0 @@ -0.21 0.37 0.39 1/719 19737 diff --git a/collector/fixtures/netstat b/collector/fixtures/netstat new file mode 100644 index 00000000..811f6232 --- /dev/null +++ b/collector/fixtures/netstat @@ -0,0 +1,4 @@ +TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLoss TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPChallengeACK TCPSYNChallenge +TcpExt: 0 0 2 0 0 0 0 0 0 0 388812 0 0 0 0 6 102471 17 9 0 0 80568 0 168808 0 4471289 26 1433940 3744565 0 1 0 0 0 0 0 0 0 0 48 0 0 0 1 0 1 0 1 115 0 0 0 0 9 0 5 0 41 4 0 0 0 0 0 0 0 1 0 0 0 0 2 5 0 0 0 0 0 0 0 2 2 +IpExt: InNoRoutes InTruncatedPkts InMcastPkts OutMcastPkts InBcastPkts OutBcastPkts InOctets OutOctets InMcastOctets OutMcastOctets InBcastOctets OutBcastOctets +IpExt: 0 0 0 0 0 0 6286396970 2786264347 0 0 0 0 diff --git a/collector/interrupts.go b/collector/interrupts.go index 79223b0c..48a26602 100644 --- a/collector/interrupts.go +++ b/collector/interrupts.go @@ -80,13 +80,17 @@ func getInterrupts() (map[string]interrupt, error) { if err != nil { return nil, err } + defer file.Close() + return parseInterrupts(file) } -func parseInterrupts(r io.ReadCloser) (map[string]interrupt, error) { - defer r.Close() - interrupts := map[string]interrupt{} - scanner := bufio.NewScanner(r) +func parseInterrupts(r io.Reader) (map[string]interrupt, error) { + var ( + interrupts = map[string]interrupt{} + scanner = bufio.NewScanner(r) + ) + if !scanner.Scan() { return nil, fmt.Errorf("%s empty", procInterrupts) } @@ -111,5 +115,6 @@ func parseInterrupts(r io.ReadCloser) (map[string]interrupt, error) { } interrupts[intName] = intr } + return interrupts, nil } diff --git a/collector/interrupts_test.go b/collector/interrupts_test.go new file mode 100644 index 00000000..fb646aa0 --- /dev/null +++ b/collector/interrupts_test.go @@ -0,0 +1,23 @@ +package collector + +import ( + "os" + "testing" +) + +func TestInterrupts(t *testing.T) { + file, err := os.Open("fixtures/interrupts") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + interrupts, err := parseInterrupts(file) + if err != nil { + t.Fatal(err) + } + + if want, got := "5031", interrupts["NMI"].values[1]; want != got { + t.Errorf("want interrupts %s, got %s", want, got) + } +} diff --git a/collector/loadavg_test.go b/collector/loadavg_test.go new file mode 100644 index 00000000..e83822a6 --- /dev/null +++ b/collector/loadavg_test.go @@ -0,0 +1,14 @@ +package collector + +import "testing" + +func TestLoad(t *testing.T) { + load, err := parseLoad("0.21 0.37 0.39 1/719 19737") + if err != nil { + t.Fatal(err) + } + + if want := 0.21; want != load { + t.Fatalf("want load %f, got %f", want, load) + } +} diff --git a/collector/megacli.go b/collector/megacli.go index cef83479..6025c99b 100644 --- a/collector/megacli.go +++ b/collector/megacli.go @@ -43,13 +43,14 @@ func init() { Factories["megacli"] = NewMegaCliCollector } -func parseMegaCliDisks(r io.ReadCloser) (map[int]map[int]map[string]string, error) { - defer r.Close() - stats := map[int]map[int]map[string]string{} - scanner := bufio.NewScanner(r) +func parseMegaCliDisks(r io.Reader) (map[int]map[int]map[string]string, error) { + var ( + stats = map[int]map[int]map[string]string{} + scanner = bufio.NewScanner(r) + curEnc = -1 + curSlot = -1 + ) - curEnc := -1 - curSlot := -1 for scanner.Scan() { var err error text := strings.TrimSpace(scanner.Text()) @@ -80,15 +81,18 @@ func parseMegaCliDisks(r io.ReadCloser) (map[int]map[int]map[string]string, erro stats[curEnc][curSlot][key] = value } } + return stats, nil } -func parseMegaCliAdapter(r io.ReadCloser) (map[string]map[string]string, error) { - defer r.Close() - raidStats := map[string]map[string]string{} - scanner := bufio.NewScanner(r) - header := "" - last := "" +func parseMegaCliAdapter(r io.Reader) (map[string]map[string]string, error) { + var ( + raidStats = map[string]map[string]string{} + scanner = bufio.NewScanner(r) + header = "" + last = "" + ) + for scanner.Scan() { text := strings.TrimSpace(scanner.Text()) if text == adapterHeaderSep { @@ -110,6 +114,7 @@ func parseMegaCliAdapter(r io.ReadCloser) (map[string]map[string]string, error) raidStats[header][key] = value } + return raidStats, nil } diff --git a/collector/meminfo.go b/collector/meminfo.go index 167b324f..13d2e179 100644 --- a/collector/meminfo.go +++ b/collector/meminfo.go @@ -67,14 +67,18 @@ func getMemInfo() (map[string]float64, error) { if err != nil { return nil, err } + defer file.Close() + return parseMemInfo(file) } -func parseMemInfo(r io.ReadCloser) (map[string]float64, error) { - defer r.Close() - memInfo := map[string]float64{} - scanner := bufio.NewScanner(r) - re := regexp.MustCompile("\\((.*)\\)") +func parseMemInfo(r io.Reader) (map[string]float64, error) { + var ( + memInfo = map[string]float64{} + scanner = bufio.NewScanner(r) + re = regexp.MustCompile("\\((.*)\\)") + ) + for scanner.Scan() { line := scanner.Text() parts := strings.Fields(string(line)) @@ -94,6 +98,6 @@ func parseMemInfo(r io.ReadCloser) (map[string]float64, error) { key = re.ReplaceAllString(key, "_${1}") memInfo[key] = fv } - return memInfo, nil + return memInfo, nil } diff --git a/collector/meminfo_test.go b/collector/meminfo_test.go new file mode 100644 index 00000000..a1c2eca4 --- /dev/null +++ b/collector/meminfo_test.go @@ -0,0 +1,27 @@ +package collector + +import ( + "os" + "testing" +) + +func TestMemInfo(t *testing.T) { + file, err := os.Open("fixtures/meminfo") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + memInfo, err := parseMemInfo(file) + if err != nil { + t.Fatal(err) + } + + if want, got := 3831959552.0, memInfo["MemTotal"]; want != got { + t.Errorf("want memory total %f, got %f", want, got) + } + + if want, got := 3787456512.0, memInfo["DirectMap2M"]; want != got { + t.Errorf("want memory directMap2M %f, got %f", want, got) + } +} diff --git a/collector/native_collector_test.go b/collector/native_collector_test.go deleted file mode 100644 index 1cb4d206..00000000 --- a/collector/native_collector_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package collector - -import ( - "io/ioutil" - "os" - "testing" -) - -const ( - loadExpected = 0.21 - - memTotalExpected = 3831959552 - memDirectMap2MExpected = 3787456512 - - interruptsNmi1Expected = "5031" - - netReceiveWlan0Bytes = "10437182923" - netTransmitTun0Packages = "934" - - diskSda4ReadsCompleted = "25353629" - diskMmcIoTimeWeighted = "68" - - testProcLoad = "fixtures/loadavg" - testProcMemInfo = "fixtures/meminfo" - testProcInterrupts = "fixtures/interrupts" - testProcNetDev = "fixtures/net-dev" - testProcDiskStats = "fixtures/diskstats" -) - -func TestLoad(t *testing.T) { - data, err := ioutil.ReadFile(testProcLoad) - if err != nil { - t.Fatal(err) - } - load, err := parseLoad(string(data)) - if err != nil { - t.Fatal(err) - } - if load != loadExpected { - t.Fatalf("Unexpected load: %f != %f", load, loadExpected) - } -} - -func TestMemInfo(t *testing.T) { - file, err := os.Open(testProcMemInfo) - if err != nil { - t.Fatal(err) - } - - memInfo, err := parseMemInfo(file) - if err != nil { - t.Fatal(err) - } - if memInfo["MemTotal"] != memTotalExpected { - t.Fatalf("Unexpected memory: %f != %d", memInfo["MemTotal"], memTotalExpected) - } - if memInfo["DirectMap2M"] != memDirectMap2MExpected { - t.Fatalf("Unexpected memory: %f != %d", memInfo["MemTotal"], memTotalExpected) - } - -} - -func TestInterrupts(t *testing.T) { - file, err := os.Open(testProcInterrupts) - if err != nil { - t.Fatal(err) - } - - interrupts, err := parseInterrupts(file) - if err != nil { - t.Fatal(err) - } - if interrupts["NMI"].values[1] != interruptsNmi1Expected { - t.Fatalf("Unexpected interrupts: %s != %s", interrupts["NMI"].values[1], - interruptsNmi1Expected) - } - -} - -func TestNetStats(t *testing.T) { - file, err := os.Open(testProcNetDev) - if err != nil { - t.Fatal(err) - } - netStats, err := parseNetStats(file) - if err != nil { - t.Fatal(err) - } - if netStats["receive"]["wlan0"]["bytes"] != netReceiveWlan0Bytes { - t.Fatalf("Unexpected netstats: %s != %s", netStats["receive"]["wlan0"]["bytes"], - netReceiveWlan0Bytes) - } - if netStats["transmit"]["tun0"]["packets"] != netTransmitTun0Packages { - t.Fatalf("Unexpected netstats: %s != %s", netStats["transmit"]["tun0"]["packets"], - netTransmitTun0Packages) - } -} - -func TestDiskStats(t *testing.T) { - file, err := os.Open(testProcDiskStats) - if err != nil { - t.Fatal(err) - } - diskStats, err := parseDiskStats(file) - if err != nil { - t.Fatal(err) - } - if diskStats["sda4"][0] != diskSda4ReadsCompleted { - t.Fatalf("Unexpected diskstats: %s != %s", diskStats["sda4"][0], - diskSda4ReadsCompleted) - } - - if diskStats["mmcblk0p2"][10] != diskMmcIoTimeWeighted { - t.Fatalf("Unexpected diskstats: %s != %s", - diskStats["mmcblk0p2"][10], diskMmcIoTimeWeighted) - } -} diff --git a/collector/netdev.go b/collector/netdev.go index 348d1bbd..efc27711 100644 --- a/collector/netdev.go +++ b/collector/netdev.go @@ -78,11 +78,12 @@ func getNetDevStats() (map[string]map[string]map[string]string, error) { if err != nil { return nil, err } + defer file.Close() + return parseNetDevStats(file) } -func parseNetDevStats(r io.ReadCloser) (map[string]map[string]map[string]string, error) { - defer r.Close() +func parseNetDevStats(r io.Reader) (map[string]map[string]map[string]string, error) { netDev := map[string]map[string]map[string]string{} netDev["transmit"] = map[string]map[string]string{} netDev["receive"] = map[string]map[string]string{} diff --git a/collector/netdev_test.go b/collector/netdev_test.go new file mode 100644 index 00000000..98011eac --- /dev/null +++ b/collector/netdev_test.go @@ -0,0 +1,27 @@ +package collector + +import ( + "os" + "testing" +) + +func TestNetDevStats(t *testing.T) { + file, err := os.Open("fixtures/net-dev") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + netStats, err := parseNetDevStats(file) + if err != nil { + t.Fatal(err) + } + + if want, got := "10437182923", netStats["receive"]["wlan0"]["bytes"]; want != got { + t.Errorf("want netstat wlan0 bytes %s, got %s", want, got) + } + + if want, got := "934", netStats["transmit"]["tun0"]["packets"]; want != got { + t.Errorf("want netstat tun0 packets %s, got %s", want, got) + } +} diff --git a/collector/netstat.go b/collector/netstat.go index 66e9d778..bca6dcd8 100644 --- a/collector/netstat.go +++ b/collector/netstat.go @@ -75,14 +75,17 @@ func getNetStats() (map[string]map[string]string, error) { if err != nil { return nil, err } + defer file.Close() + return parseNetStats(file) } -func parseNetStats(r io.ReadCloser) (map[string]map[string]string, error) { - defer r.Close() - netStats := map[string]map[string]string{} +func parseNetStats(r io.Reader) (map[string]map[string]string, error) { + var ( + netStats = map[string]map[string]string{} + scanner = bufio.NewScanner(r) + ) - scanner := bufio.NewScanner(r) for scanner.Scan() { nameParts := strings.Split(string(scanner.Text()), " ") scanner.Scan() @@ -98,5 +101,6 @@ func parseNetStats(r io.ReadCloser) (map[string]map[string]string, error) { netStats[protocol][nameParts[i]] = valueParts[i] } } + return netStats, nil } diff --git a/collector/netstat_test.go b/collector/netstat_test.go new file mode 100644 index 00000000..a2b8f356 --- /dev/null +++ b/collector/netstat_test.go @@ -0,0 +1,27 @@ +package collector + +import ( + "os" + "testing" +) + +func TestNetStats(t *testing.T) { + file, err := os.Open("fixtures/netstat") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + netStats, err := parseNetStats(file) + if err != nil { + t.Fatal(err) + } + + if want, got := "102471", netStats["TcpExt"]["DelayedACKs"]; want != got { + t.Errorf("want netstat TCP DelayedACKs %s, got %s", want, got) + } + + if want, got := "2786264347", netStats["IpExt"]["OutOctets"]; want != got { + t.Errorf("want netstat IP OutOctets %s, got %s", want, got) + } +}