Skip to content

Commit bc2175f

Browse files
author
Per Abich
committed
Adding some test for the showq part. Found a minor bug.
1 parent 0436fed commit bc2175f

File tree

5 files changed

+230
-17
lines changed

5 files changed

+230
-17
lines changed

mock/HistogramVecMock.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package mock
2+
3+
import "github.com/prometheus/client_golang/prometheus"
4+
5+
type HistorgramVecMock struct {
6+
mock HistogramMock
7+
}
8+
9+
func (m *HistorgramVecMock) Describe(chan<- *prometheus.Desc) {
10+
panic("implement me")
11+
}
12+
13+
func (m *HistorgramVecMock) GetMetricWith(prometheus.Labels) (prometheus.Observer, error) {
14+
panic("implement me")
15+
}
16+
17+
func (m *HistorgramVecMock) GetMetricWithLabelValues(lvs ...string) (prometheus.Observer, error) {
18+
panic("implement me")
19+
}
20+
21+
func (m *HistorgramVecMock) With(prometheus.Labels) prometheus.Observer {
22+
panic("implement me")
23+
}
24+
25+
func (m *HistorgramVecMock) WithLabelValues(...string) prometheus.Observer {
26+
return m.mock
27+
}
28+
29+
func (m *HistorgramVecMock) CurryWith(prometheus.Labels) (prometheus.ObserverVec, error) {
30+
panic("implement me")
31+
}
32+
33+
func (m *HistorgramVecMock) MustCurryWith(prometheus.Labels) prometheus.ObserverVec {
34+
panic("implement me")
35+
}
36+
37+
func (m *HistorgramVecMock) Collect(chan<- prometheus.Metric) {
38+
panic("implement me")
39+
}
40+
func (m *HistorgramVecMock) GetSum() float64 {
41+
return *m.mock.sum
42+
}
43+
44+
func NewHistogramVecMock() *HistorgramVecMock {
45+
return &HistorgramVecMock{mock: *NewHistogramMock()}
46+
}

mock/HistorgramMock.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package mock
2+
3+
import (
4+
"github.com/prometheus/client_golang/prometheus"
5+
"github.com/prometheus/client_model/go"
6+
)
7+
8+
type HistogramMock struct {
9+
sum *float64
10+
}
11+
12+
func NewHistogramMock() *HistogramMock {
13+
return &HistogramMock{sum: new(float64)}
14+
}
15+
16+
func (HistogramMock) Desc() *prometheus.Desc {
17+
panic("implement me")
18+
}
19+
20+
func (HistogramMock) Write(*io_prometheus_client.Metric) error {
21+
panic("implement me")
22+
}
23+
24+
func (HistogramMock) Describe(chan<- *prometheus.Desc) {
25+
panic("implement me")
26+
}
27+
28+
func (HistogramMock) Collect(chan<- prometheus.Metric) {
29+
panic("implement me")
30+
}
31+
32+
func (h HistogramMock) Observe(value float64) {
33+
*h.sum += value
34+
}

postfix_exporter.go

+25-17
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,6 @@ func CollectShowqFromReader(file io.Reader, ch chan<- prometheus.Metric) error {
9494

9595
// CollectTextualShowqFromReader parses Postfix's textual showq output.
9696
func CollectTextualShowqFromReader(file io.Reader, ch chan<- prometheus.Metric) error {
97-
scanner := bufio.NewScanner(file)
98-
scanner.Split(bufio.ScanLines)
99-
100-
// Regular expression for matching postqueue's output. Example:
101-
// "A07A81514 5156 Tue Feb 14 13:13:54 MAILER-DAEMON"
102-
messageLine := regexp.MustCompile(`^[0-9A-F]+([\*!]?) +(\d+) (\w{3} \w{3} +\d+ +\d+:\d{2}:\d{2}) +`)
10397

10498
// Histograms tracking the messages by size and age.
10599
sizeHistogram := prometheus.NewHistogramVec(
@@ -119,34 +113,51 @@ func CollectTextualShowqFromReader(file io.Reader, ch chan<- prometheus.Metric)
119113
},
120114
[]string{"queue"})
121115

116+
err := CollectTextualShowqFromScanner(sizeHistogram, ageHistogram, file)
117+
118+
sizeHistogram.Collect(ch)
119+
ageHistogram.Collect(ch)
120+
return err
121+
}
122+
123+
func CollectTextualShowqFromScanner(sizeHistogram prometheus.ObserverVec, ageHistogram prometheus.ObserverVec, file io.Reader) error {
124+
scanner := bufio.NewScanner(file)
125+
scanner.Split(bufio.ScanLines)
122126
// Initialize all queue buckets to zero.
123127
for _, q := range []string{"active", "hold", "other"} {
124128
sizeHistogram.WithLabelValues(q)
125129
ageHistogram.WithLabelValues(q)
126130
}
127131

128-
now := time.Now()
129132
location, err := time.LoadLocation("Local")
130133
if err != nil {
131134
log.Println(err)
132135
}
133136

137+
// Regular expression for matching postqueue's output. Example:
138+
// "A07A81514 5156 Tue Feb 14 13:13:54 MAILER-DAEMON"
139+
messageLine := regexp.MustCompile(`^[0-9A-F]+([\*!]?) +(\d+) (\w{3} \w{3} +\d+ +\d+:\d{2}:\d{2}) +`)
140+
134141
for scanner.Scan() {
135-
matches := messageLine.FindStringSubmatch(scanner.Text())
136-
if matches != nil {
142+
text := scanner.Text()
143+
matches := messageLine.FindStringSubmatch(text)
144+
if matches == nil {
137145
continue
138146
}
147+
queueMatch := matches[1]
148+
sizeMatch := matches[2]
149+
dateMatch := matches[3]
139150

140151
// Derive the name of the message queue.
141152
queue := "other"
142-
if matches[1] == "*" {
153+
if queueMatch == "*" {
143154
queue = "active"
144-
} else if matches[1] == "!" {
155+
} else if queueMatch == "!" {
145156
queue = "hold"
146157
}
147158

148159
// Parse the message size.
149-
size, err := strconv.ParseFloat(matches[2], 64)
160+
size, err := strconv.ParseFloat(sizeMatch, 64)
150161
if err != nil {
151162
return err
152163
}
@@ -155,11 +166,11 @@ func CollectTextualShowqFromReader(file io.Reader, ch chan<- prometheus.Metric)
155166
// output contains no year number. Assume it
156167
// applies to the last year for which the
157168
// message date doesn't exceed time.Now().
158-
date, err := time.ParseInLocation("Mon Jan 2 15:04:05",
159-
matches[3], location)
169+
date, err := time.ParseInLocation("Mon Jan 2 15:04:05", dateMatch, location)
160170
if err != nil {
161171
return err
162172
}
173+
now := time.Now()
163174
date = date.AddDate(now.Year(), 0, 0)
164175
if date.After(now) {
165176
date = date.AddDate(-1, 0, 0)
@@ -168,9 +179,6 @@ func CollectTextualShowqFromReader(file io.Reader, ch chan<- prometheus.Metric)
168179
sizeHistogram.WithLabelValues(queue).Observe(size)
169180
ageHistogram.WithLabelValues(queue).Observe(now.Sub(date).Seconds())
170181
}
171-
172-
sizeHistogram.Collect(ch)
173-
ageHistogram.Collect(ch)
174182
return scanner.Err()
175183
}
176184

showq_test.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"github.com/kumina/postfix_exporter/mock"
5+
"github.com/stretchr/testify/assert"
6+
"os"
7+
"testing"
8+
)
9+
10+
func TestCollectShowqFromReader(t *testing.T) {
11+
type args struct {
12+
file string
13+
}
14+
tests := []struct {
15+
name string
16+
args args
17+
wantErr bool
18+
expectedTotalCount float64
19+
}{
20+
{
21+
name: "basic test",
22+
args: args{
23+
file: "testdata/showq.txt",
24+
},
25+
wantErr: false,
26+
expectedTotalCount: 118702,
27+
},
28+
}
29+
for _, tt := range tests {
30+
t.Run(tt.name, func(t *testing.T) {
31+
file, err := os.Open(tt.args.file)
32+
if err != nil {
33+
t.Error(err)
34+
}
35+
36+
sizeHistogram := mock.NewHistogramVecMock()
37+
ageHistogram := mock.NewHistogramVecMock()
38+
if err := CollectTextualShowqFromScanner(sizeHistogram, ageHistogram, file); (err != nil) != tt.wantErr {
39+
t.Errorf("CollectShowqFromReader() error = %v, wantErr %v", err, tt.wantErr)
40+
}
41+
assert.Equal(t, tt.expectedTotalCount, sizeHistogram.GetSum(), "Expected a lot more data.")
42+
assert.Less(t, 0.0, ageHistogram.GetSum(), "Age not greater than 0")
43+
})
44+
}
45+
}

testdata/showq.txt

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
2+
C420820802* 4387 Mon Feb 24 13:35:18 [email protected]
3+
4+
5+
8D5D4205B9* 4033 Mon Feb 24 13:22:16 [email protected]
6+
7+
8+
7465520414* 4043 Mon Feb 24 13:22:16 [email protected]
9+
10+
11+
3E2F72070A* 5301 Mon Feb 24 13:35:39 [email protected]
12+
13+
14+
542032060A* 5828 Mon Feb 24 13:34:46 [email protected]
15+
16+
17+
4B96A2037C* 9868 Mon Feb 24 13:32:03 [email protected]
18+
19+
20+
E88EA20796* 5956 Mon Feb 24 13:34:55 [email protected]
21+
22+
23+
8C9912052C* 4047 Mon Feb 24 13:22:16 [email protected]
24+
25+
26+
70BDA2079B* 4404 Mon Feb 24 13:35:18 [email protected]
27+
28+
29+
76E6A20536* 3875 Mon Feb 24 13:21:20 [email protected]
30+
31+
32+
92C662062A* 3864 Mon Feb 24 13:21:20 [email protected]
33+
34+
35+
BA9BC2071E* 4387 Mon Feb 24 13:35:18 [email protected]
36+
37+
38+
9A67020670* 4393 Mon Feb 24 13:34:06 [email protected]
39+
40+
41+
651AC20138* 3872 Mon Feb 24 13:23:17 [email protected]
42+
43+
44+
4F16D20516* 4052 Mon Feb 24 13:24:38 [email protected]
45+
46+
47+
C9C4A20501* 5099 Mon Feb 24 13:14:10 [email protected]
48+
49+
50+
0572820D64 4098 Sat Feb 22 00:44:54 [email protected]
51+
(host mail.wekudata.com[37.208.0.7] said: 452 4.2.2 Quota exceeded ([email protected]) (in reply to RCPT TO command))
52+
53+
54+
0B2C320952 4173 Sat Feb 22 00:42:07 [email protected]
55+
(host alt1.gmail-smtp-in.l.google.com[108.177.97.26] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2 https://support.google.com/mail/?p=OverQuotaTemp q24si6538316pgt.498 - gsmtp (in reply to RCPT TO command))
56+
57+
58+
0CC2B22124 10926 Fri Feb 21 13:31:58 [email protected]
59+
(host alt1.gmail-smtp-in.l.google.com[108.177.97.26] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2 https://support.google.com/mail/?p=OverQuotaTemp f10si11999094pgj.597 - gsmtp (in reply to RCPT TO command))
60+
61+
62+
0C84020606 4898 Mon Feb 24 08:30:34 [email protected]
63+
(host alt1.gmail-smtp-in.l.google.com[108.177.97.26] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2 https://support.google.com/mail/?p=OverQuotaTemp 2si12536346pld.231 - gsmtp (in reply to RCPT TO command))
64+
65+
66+
04EAA203C0 4133 Mon Feb 24 12:21:58 [email protected]
67+
(host alt1.gmail-smtp-in.l.google.com[108.177.97.26] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2 https://support.google.com/mail/?p=OverQuotaTemp i16si12220651pfq.60 - gsmtp (in reply to RCPT TO command))
68+
69+
70+
00C33202B6 4823 Mon Feb 24 11:32:37 [email protected]
71+
(connect to gafe.se[151.252.30.111]:25: Connection refused)
72+
73+
74+
046E0218CA 4154 Mon Feb 24 00:13:12 [email protected]
75+
(host alt1.gmail-smtp-in.l.google.com[108.177.97.26] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2 https://support.google.com/mail/?p=OverQuotaTemp y1si11835269pgi.474 - gsmtp (in reply to RCPT TO command))
76+
77+
78+
06373212DC 4088 Sat Feb 22 00:34:11 [email protected]
79+
(connect to smtp.falun.se[192.121.234.25]:25: Connection timed out)
80+

0 commit comments

Comments
 (0)