Skip to content

Commit fa1cd1a

Browse files
test: refactor reload test (#930)
1 parent eb04c89 commit fa1cd1a

File tree

1 file changed

+82
-44
lines changed

1 file changed

+82
-44
lines changed

reload_test.go

Lines changed: 82 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,26 @@ package sql_exporter
44

55
import (
66
"fmt"
7+
"io"
8+
"log/slog"
79
_ "net/http/pprof"
810
"os"
911
"path/filepath"
1012
"runtime"
11-
"strings"
1213
"testing"
1314

1415
_ "github.com/mithrandie/csvq-driver"
16+
"go.yaml.in/yaml/v3"
1517

1618
"github.com/prometheus/client_golang/prometheus"
1719
)
1820

19-
// setupCSVDir creates a temp directory with a minimal CSV file usable as a table.
21+
// setupCSVDirs creates a temp directory with a minimal CSV file usable as a table.
2022
func setupCSVDirs(t *testing.T, n int) []string {
2123
t.Helper()
2224
base := t.TempDir()
2325
dirs := make([]string, n)
24-
for i := range n {
26+
for i := range dirs {
2527
dir := filepath.Join(base, fmt.Sprintf("csv_%d", i))
2628
if err := os.MkdirAll(dir, 0o755); err != nil {
2729
t.Fatalf("mkdir CSV dir %d: %v", i, err)
@@ -34,55 +36,86 @@ func setupCSVDirs(t *testing.T, n int) []string {
3436
return dirs
3537
}
3638

37-
// writeConfig writes a sql_exporter YAML config file pointing at csvDir with
38-
// n targets, returning the config file path.
39-
func writeConfig(t *testing.T, dirs []string, n int) string {
39+
func writeConfig(t *testing.T, dirs []string) string {
4040
t.Helper()
4141

42-
var sb strings.Builder
43-
for i := range n {
44-
fmt.Fprintf(&sb, `
45-
- collector_name: col%d
46-
metrics:
47-
- metric_name: csvq_value_%d
48-
type: gauge
49-
help: "test metric %d"
50-
values: [value]
51-
query: "SELECT value FROM metrics"
52-
`, i, i, i)
42+
type metric struct {
43+
Name string `yaml:"metric_name"`
44+
Type string `yaml:"type"`
45+
Help string `yaml:"help"`
46+
Values []string `yaml:"values"`
47+
Query string `yaml:"query"`
5348
}
54-
collectors := sb.String()
55-
56-
sb.Reset()
57-
for i := range n {
58-
fmt.Fprintf(&sb, " target%d: csvq:%s\n", i, dirs[i])
49+
type collector struct {
50+
Name string `yaml:"collector_name"`
51+
Metrics []metric `yaml:"metrics"`
52+
}
53+
type staticConfig struct {
54+
Targets map[string]string `yaml:"targets"`
55+
}
56+
type job struct {
57+
Name string `yaml:"job_name"`
58+
Collectors []string `yaml:"collectors"`
59+
StaticConfigs []staticConfig `yaml:"static_configs"`
60+
}
61+
type global struct {
62+
ScrapeTimeout string `yaml:"scrape_timeout"`
63+
ScrapeTimeoutOffset string `yaml:"scrape_timeout_offset"`
64+
MinInterval string `yaml:"min_interval"`
65+
MaxConnections int `yaml:"max_connections"`
66+
MaxIdleConnections int `yaml:"max_idle_connections"`
67+
}
68+
type cfg struct {
69+
Global global `yaml:"global"`
70+
Collectors []collector `yaml:"collectors"`
71+
Jobs []job `yaml:"jobs"`
5972
}
60-
targets := sb.String()
61-
62-
content := fmt.Sprintf(`
63-
global:
64-
scrape_timeout: 10s
65-
scrape_timeout_offset: 500ms
66-
min_interval: 0s
67-
max_connections: 3
68-
max_idle_connections: 3
69-
70-
collector_files: []
7173

72-
collectors:%s
74+
n := len(dirs)
75+
collectors := make([]collector, n)
76+
collectorNames := make([]string, n)
77+
targets := make(map[string]string, n)
78+
79+
for i := range dirs {
80+
name := fmt.Sprintf("col%d", i)
81+
collectorNames[i] = name
82+
collectors[i] = collector{
83+
Name: name,
84+
Metrics: []metric{{
85+
Name: fmt.Sprintf("csvq_value_%d", i),
86+
Type: "gauge",
87+
Help: fmt.Sprintf("test metric %d", i),
88+
Values: []string{"value"},
89+
Query: "SELECT value FROM metrics",
90+
}},
91+
}
92+
targets[fmt.Sprintf("target%d", i)] = "csvq:" + dirs[i]
93+
}
7394

74-
jobs:
75-
- job_name: test_job
76-
collectors: [col0, col1, col2, col3, col4, col5, col6, col7, col8, col9]
77-
static_configs:
78-
- targets:
79-
%s`, collectors, targets)
95+
c := cfg{
96+
Global: global{
97+
ScrapeTimeout: "10s",
98+
ScrapeTimeoutOffset: "500ms",
99+
MinInterval: "0s",
100+
MaxConnections: 3,
101+
MaxIdleConnections: 3,
102+
},
103+
Collectors: collectors,
104+
Jobs: []job{{
105+
Name: "test_job",
106+
Collectors: collectorNames,
107+
StaticConfigs: []staticConfig{{Targets: targets}},
108+
}},
109+
}
80110

111+
data, err := yaml.Marshal(c)
112+
if err != nil {
113+
t.Fatalf("marshal config: %v", err)
114+
}
81115
cfgFile := filepath.Join(t.TempDir(), "sql_exporter.yml")
82-
if err := os.WriteFile(cfgFile, []byte(content), 0o644); err != nil {
116+
if err := os.WriteFile(cfgFile, data, 0o644); err != nil {
83117
t.Fatalf("write config: %v", err)
84118
}
85-
86119
return cfgFile
87120
}
88121

@@ -132,7 +165,7 @@ func TestReloadMemoryLeak(t *testing.T) {
132165
)
133166

134167
dirs := setupCSVDirs(t, numTargets)
135-
cfgFile := writeConfig(t, dirs, numTargets)
168+
cfgFile := writeConfig(t, dirs)
136169

137170
e, err := NewExporter(cfgFile, prometheus.NewRegistry())
138171
if err != nil {
@@ -143,6 +176,11 @@ func TestReloadMemoryLeak(t *testing.T) {
143176

144177
t.Logf("goroutine delta=%d (expected <= %d)", delta, tolerance)
145178
if delta > tolerance {
146-
t.Errorf("expected goroutine delta <= %d, got %d — leak still present", tolerance, delta)
179+
t.Errorf("expected goroutine delta <= %d, got %d — leak suspected", tolerance, delta)
147180
}
148181
}
182+
183+
func TestMain(m *testing.M) {
184+
slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil)))
185+
os.Exit(m.Run())
186+
}

0 commit comments

Comments
 (0)