Skip to content

Commit 56022d3

Browse files
committed
PMM-10278 Refactor
1 parent ee201fe commit 56022d3

15 files changed

+235
-175
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
/.metrics.*.removed
2121
/tools/src
2222
/vendor
23-
/percona/postgres_exporter
24-
/percona/postgres_exporter_percona
23+
/percona_tests/postgres_exporter
24+
/percona_tests/postgres_exporter_percona

percona/Makefile renamed to percona_tests/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
test-performance:
2-
go test -v process_time_test.go -run TestPerformance -args -doRun=true
2+
go test -v -run '^TestPerformance$\' -args -doRun=true
3+
4+
test-metrics:
5+
go test -v -run '^TestMetrics$\' -args -doRun=true
6+
7+
# env preparation
38

49
# download exporter from provided feature build's client binary url
510
prepare-exporter:

percona/env_prepare_test.go renamed to percona_tests/env_prepare_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package upstream_update
1+
package percona_tests
22

33
import (
44
"archive/tar"

percona_tests/metrics_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package percona_tests
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestMetrics(t *testing.T) {
8+
// put postgres_exporter and postgres_exporter_percona files in 'percona' folder
9+
// or use TestPrepareExporters to download exporters from feature build
10+
if doRun == nil || !*doRun {
11+
t.Skip("For manual runs only through make")
12+
return
13+
}
14+
15+
cmd, _, collectOutput, err := launchExporter("../percona_tests/postgres_exporter")
16+
if err != nil {
17+
t.Error(err, "Failed to launch exporter")
18+
return
19+
}
20+
21+
err = stopExporter(cmd, collectOutput)
22+
if err != nil {
23+
t.Error(err, "Failed to stop exporter")
24+
return
25+
}
26+
}
Lines changed: 7 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
1-
package upstream_update
1+
package percona_tests
22

33
import (
4-
"bytes"
5-
"compress/gzip"
64
"flag"
75
"fmt"
8-
"io"
96
"io/ioutil"
10-
"net"
11-
"net/http"
12-
"os"
13-
"os/exec"
14-
"path/filepath"
157
"strconv"
168
"strings"
179
"testing"
@@ -21,20 +13,9 @@ import (
2113
"github.com/pkg/errors"
2214
"github.com/stretchr/testify/assert"
2315
"github.com/tklauser/go-sysconf"
24-
"golang.org/x/sys/unix"
2516
)
2617

2718
const (
28-
postgresHost = "127.0.0.1"
29-
postgresPort = 5432
30-
postgresUser = "postgres"
31-
postgresPassword = "postgres"
32-
33-
exporterWaitTimeoutMs = 3000 // time to wait for exporter process start
34-
35-
portRangeStart = 20000 // exporter web interface listening port
36-
portRangeEnd = 20100 // exporter web interface listening port
37-
3819
repeatCount = 5
3920
scrapesCount = 50
4021
)
@@ -66,11 +47,11 @@ func TestPerformance(t *testing.T) {
6647

6748
var updated, original *StatsData
6849
t.Run("upstream exporter", func(t *testing.T) {
69-
updated = doTestStats(t, repeatCount, scrapesCount, "../percona/postgres_exporter")
50+
updated = doTestStats(t, repeatCount, scrapesCount, "../percona_tests/postgres_exporter")
7051
})
7152

7253
t.Run("percona exporter", func(t *testing.T) {
73-
original = doTestStats(t, repeatCount, scrapesCount, "../percona/postgres_exporter_percona")
54+
original = doTestStats(t, repeatCount, scrapesCount, "../percona_tests/postgres_exporter_percona")
7455
})
7556

7657
printStats(original, updated)
@@ -143,80 +124,10 @@ func doTestStats(t *testing.T, cnt int, size int, fileName string) *StatsData {
143124
return &st
144125
}
145126

146-
func checkPort(port int) bool {
147-
ln, err := net.Listen("tcp", ":"+fmt.Sprint(port))
148-
if err != nil {
149-
return false
150-
}
151-
152-
_ = ln.Close()
153-
return true
154-
}
155-
156127
func doTest(iterations int, fileName string) (cpu, hwm, data int64, _ error) {
157-
lines, err := os.ReadFile("test.exporter-flags.txt")
128+
cmd, port, collectOutput, err := launchExporter(fileName)
158129
if err != nil {
159-
return 0, 0, 0, errors.Wrapf(err, "Unable to read exporter args file")
160-
}
161-
162-
var port = -1
163-
for i := portRangeStart; i < portRangeEnd; i++ {
164-
if checkPort(i) {
165-
port = i
166-
break
167-
}
168-
}
169-
170-
if port == -1 {
171-
return 0, 0, 0, errors.Wrapf(err, "Failed to find free port in range [%d..%d]", portRangeStart, portRangeEnd)
172-
}
173-
174-
linesStr := string(lines)
175-
linesStr += fmt.Sprintf("\n--web.listen-address=127.0.0.1:%d", port)
176-
177-
absolutePath, _ := filepath.Abs("custom-queries")
178-
linesStr += fmt.Sprintf("\n--collect.custom_query.hr.directory=%s/high-resolution", absolutePath)
179-
linesStr += fmt.Sprintf("\n--collect.custom_query.mr.directory=%s/medium-resolution", absolutePath)
180-
linesStr += fmt.Sprintf("\n--collect.custom_query.lr.directory=%s/low-resolution", absolutePath)
181-
182-
linesArr := strings.Split(linesStr, "\n")
183-
184-
dsn := fmt.Sprintf("DATA_SOURCE_NAME=postgresql://%s:%s@%s:%d/postgres?sslmode=disable", postgresUser, postgresPassword, postgresHost, postgresPort)
185-
186-
cmd := exec.Command(fileName, linesArr...)
187-
cmd.Env = os.Environ()
188-
cmd.Env = append(cmd.Env, dsn)
189-
190-
var outBuffer, errorBuffer bytes.Buffer
191-
cmd.Stdout = &outBuffer
192-
cmd.Stderr = &errorBuffer
193-
194-
collectOutput := func() string {
195-
result := ""
196-
outStr := outBuffer.String()
197-
if outStr == "" {
198-
result = "Process stdOut was empty. "
199-
} else {
200-
result = fmt.Sprintf("Process stdOut:\n%s\n", outStr)
201-
}
202-
errStr := errorBuffer.String()
203-
if errStr == "" {
204-
result += "Process stdErr was empty."
205-
} else {
206-
result += fmt.Sprintf("Process stdErr:\n%s\n", errStr)
207-
}
208-
209-
return result
210-
}
211-
212-
err = cmd.Start()
213-
if err != nil {
214-
return 0, 0, 0, errors.Wrapf(err, "Failed to start exporter.%s", collectOutput())
215-
}
216-
217-
err = waitForExporter(port)
218-
if err != nil {
219-
return 0, 0, 0, errors.Wrapf(err, "Failed to wait for exporter.%s", collectOutput())
130+
return 0, 0, 0, err
220131
}
221132

222133
total1 := getCPUTime(cmd.Process.Pid)
@@ -234,14 +145,9 @@ func doTest(iterations int, fileName string) (cpu, hwm, data int64, _ error) {
234145

235146
hwm, data = getCPUMem(cmd.Process.Pid)
236147

237-
err = cmd.Process.Signal(unix.SIGINT)
148+
err = stopExporter(cmd, collectOutput)
238149
if err != nil {
239-
return 0, 0, 0, errors.Wrapf(err, "Failed to send SIGINT to exporter process.%s\n", collectOutput())
240-
}
241-
242-
err = cmd.Wait()
243-
if err != nil && err.Error() != "signal: interrupt" {
244-
return 0, 0, 0, errors.Wrapf(err, "Failed to wait for exporter process termination.%s\n", collectOutput())
150+
return 0, 0, 0, err
245151
}
246152

247153
return total2 - total1, hwm, data, nil
@@ -311,73 +217,3 @@ func printStats(original, updated *StatsData) {
311217
fmt.Printf("DATA, kB\t%.1f\t%.1f\t%+.0f%%\n", original.meanData, updated.meanData, calculatePerc(original.meanData, updated.meanData))
312218
fmt.Println()
313219
}
314-
315-
func tryGetMetrics(port int) error {
316-
uri := fmt.Sprintf("http://127.0.0.1:%d/metrics", port)
317-
client := new(http.Client)
318-
319-
request, err := http.NewRequest("GET", uri, nil)
320-
if err != nil {
321-
return err
322-
}
323-
request.Header.Add("Accept-Encoding", "gzip")
324-
325-
response, err := client.Do(request)
326-
327-
if err != nil {
328-
return fmt.Errorf("failed to get response from exporters web interface: %w", err)
329-
}
330-
331-
if response.StatusCode != http.StatusOK {
332-
return fmt.Errorf("failed to get response from exporters web interface: %w", err)
333-
}
334-
335-
// Check that the server actually sent compressed data
336-
var reader io.ReadCloser
337-
enc := response.Header.Get("Content-Encoding")
338-
switch enc {
339-
case "gzip":
340-
reader, err = gzip.NewReader(response.Body)
341-
if err != nil {
342-
return fmt.Errorf("failed to create gzip reader: %w", err)
343-
}
344-
defer reader.Close()
345-
default:
346-
reader = response.Body
347-
}
348-
349-
buf := new(strings.Builder)
350-
_, err = io.Copy(buf, reader)
351-
if err != nil {
352-
return err
353-
}
354-
355-
rr := buf.String()
356-
if rr == "" {
357-
return fmt.Errorf("failed to read response")
358-
}
359-
360-
err = response.Body.Close()
361-
if err != nil {
362-
return fmt.Errorf("failed to close response: %w", err)
363-
}
364-
365-
return nil
366-
}
367-
368-
func waitForExporter(port int) error {
369-
watchdog := exporterWaitTimeoutMs
370-
371-
for ; tryGetMetrics(port) != nil && watchdog > 0; watchdog-- {
372-
time.Sleep(1 * time.Millisecond)
373-
if watchdog < 1000 {
374-
time.Sleep(1 * time.Millisecond)
375-
}
376-
}
377-
378-
if watchdog == 0 {
379-
return fmt.Errorf("failed to wait for exporter (on port %d)", port)
380-
}
381-
382-
return nil
383-
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)