1
- package upstream_update
1
+ package percona_tests
2
2
3
3
import (
4
- "bytes"
5
- "compress/gzip"
6
4
"flag"
7
5
"fmt"
8
- "io"
9
6
"io/ioutil"
10
- "net"
11
- "net/http"
12
- "os"
13
- "os/exec"
14
- "path/filepath"
15
7
"strconv"
16
8
"strings"
17
9
"testing"
@@ -21,20 +13,9 @@ import (
21
13
"github.com/pkg/errors"
22
14
"github.com/stretchr/testify/assert"
23
15
"github.com/tklauser/go-sysconf"
24
- "golang.org/x/sys/unix"
25
16
)
26
17
27
18
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
-
38
19
repeatCount = 5
39
20
scrapesCount = 50
40
21
)
@@ -66,11 +47,11 @@ func TestPerformance(t *testing.T) {
66
47
67
48
var updated , original * StatsData
68
49
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" )
70
51
})
71
52
72
53
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" )
74
55
})
75
56
76
57
printStats (original , updated )
@@ -143,80 +124,10 @@ func doTestStats(t *testing.T, cnt int, size int, fileName string) *StatsData {
143
124
return & st
144
125
}
145
126
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
-
156
127
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 )
158
129
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
220
131
}
221
132
222
133
total1 := getCPUTime (cmd .Process .Pid )
@@ -234,14 +145,9 @@ func doTest(iterations int, fileName string) (cpu, hwm, data int64, _ error) {
234
145
235
146
hwm , data = getCPUMem (cmd .Process .Pid )
236
147
237
- err = cmd . Process . Signal ( unix . SIGINT )
148
+ err = stopExporter ( cmd , collectOutput )
238
149
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
245
151
}
246
152
247
153
return total2 - total1 , hwm , data , nil
@@ -311,73 +217,3 @@ func printStats(original, updated *StatsData) {
311
217
fmt .Printf ("DATA, kB\t %.1f\t %.1f\t %+.0f%%\n " , original .meanData , updated .meanData , calculatePerc (original .meanData , updated .meanData ))
312
218
fmt .Println ()
313
219
}
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
- }
0 commit comments