Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 03:15 UTC
caddytest: Support configuration defaults override (#6850)
baruchyahalom committed
Mar 3, 2025 at 16:35 UTC
8861eae22350d9e8f94653db951faf85a50a82da
1 file changed
+42
-21
caddytest/caddytest.go
+42
-21
@@ -31,8 +31,8 @@ import (
31
_ "github.com/caddyserver/caddy/v2/modules/standard"
32
)
33
34
-// Defaults store any configuration required to make the tests run
35
-type Defaults struct {
34
+// Config store any configuration required to make the tests run
35
+type Config struct {
36
// Port we expect caddy to listening on
37
AdminPort int
38
// Certificates we expect to be loaded before attempting to run the tests
@@ -44,7 +44,7 @@ type Defaults struct {
44
}
45
46
// Default testing values
47
-var Default = Defaults{
47
+var Default = Config{
48
AdminPort: 2999, // different from what a real server also running on a developer's machine might be
49
Certificates: []string{"/caddy.localhost.crt", "/caddy.localhost.key"},
50
TestRequestTimeout: 5 * time.Second,
@@ -61,6 +61,7 @@ type Tester struct {
61
Client *http.Client
62
configLoaded bool
63
t testing.TB
64
+ config Config
65
}
66
67
// NewTester will create a new testing client with an attached cookie jar
@@ -78,9 +79,29 @@ func NewTester(t testing.TB) *Tester {
79
},
80
configLoaded: false,
81
t: t,
82
+ config: Default,
83
}
84
}
85
86
+// WithDefaultOverrides this will override the default test configuration with the provided values.
87
+func (tc *Tester) WithDefaultOverrides(overrides Config) *Tester {
88
+ if overrides.AdminPort != 0 {
89
+ tc.config.AdminPort = overrides.AdminPort
90
+ }
91
+ if len(overrides.Certificates) > 0 {
92
+ tc.config.Certificates = overrides.Certificates
93
+ }
94
+ if overrides.TestRequestTimeout != 0 {
95
+ tc.config.TestRequestTimeout = overrides.TestRequestTimeout
96
+ tc.Client.Timeout = overrides.TestRequestTimeout
97
+ }
98
+ if overrides.LoadRequestTimeout != 0 {
99
+ tc.config.LoadRequestTimeout = overrides.LoadRequestTimeout
100
+ }
101
+
102
+ return tc
103
+}
104
+
105
type configLoadError struct {
106
Response string
107
}
@@ -113,7 +134,7 @@ func (tc *Tester) initServer(rawConfig string, configType string) error {
134
return nil
135
}
136
116
- err := validateTestPrerequisites(tc.t)
137
+ err := validateTestPrerequisites(tc)
138
if err != nil {
139
tc.t.Skipf("skipping tests as failed integration prerequisites. %s", err)
140
return nil
@@ -121,7 +142,7 @@ func (tc *Tester) initServer(rawConfig string, configType string) error {
142
143
tc.t.Cleanup(func() {
144
if tc.t.Failed() && tc.configLoaded {
124
- res, err := http.Get(fmt.Sprintf("http://localhost:%d/config/", Default.AdminPort))
145
+ res, err := http.Get(fmt.Sprintf("http://localhost:%d/config/", tc.config.AdminPort))
146
if err != nil {
147
tc.t.Log("unable to read the current config")
148
return
@@ -151,10 +172,10 @@ func (tc *Tester) initServer(rawConfig string, configType string) error {
172
tc.t.Logf("After: %s", rawConfig)
173
}
174
client := &http.Client{
154
- Timeout: Default.LoadRequestTimeout,
175
+ Timeout: tc.config.LoadRequestTimeout,
176
}
177
start := time.Now()
157
- req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/load", Default.AdminPort), strings.NewReader(rawConfig))
178
+ req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/load", tc.config.AdminPort), strings.NewReader(rawConfig))
179
if err != nil {
180
tc.t.Errorf("failed to create request. %s", err)
181
return err
@@ -205,11 +226,11 @@ func (tc *Tester) ensureConfigRunning(rawConfig string, configType string) error
226
}
227
228
client := &http.Client{
208
- Timeout: Default.LoadRequestTimeout,
229
+ Timeout: tc.config.LoadRequestTimeout,
230
}
231
232
fetchConfig := func(client *http.Client) any {
212
- resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", Default.AdminPort))
233
+ resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", tc.config.AdminPort))
234
if err != nil {
235
return nil
236
}
@@ -237,30 +258,30 @@ func (tc *Tester) ensureConfigRunning(rawConfig string, configType string) error
258
}
259
260
const initConfig = `{
240
- admin localhost:2999
261
+ admin localhost:%d
262
}
263
`
264
265
// validateTestPrerequisites ensures the certificates are available in the
266
// designated path and Caddy sub-process is running.
246
-func validateTestPrerequisites(t testing.TB) error {
267
+func validateTestPrerequisites(tc *Tester) error {
268
// check certificates are found
248
- for _, certName := range Default.Certificates {
269
+ for _, certName := range tc.config.Certificates {
270
if _, err := os.Stat(getIntegrationDir() + certName); errors.Is(err, fs.ErrNotExist) {
271
return fmt.Errorf("caddy integration test certificates (%s) not found", certName)
272
}
273
}
274
254
- if isCaddyAdminRunning() != nil {
275
+ if isCaddyAdminRunning(tc) != nil {
276
// setup the init config file, and set the cleanup afterwards
277
f, err := os.CreateTemp("", "")
278
if err != nil {
279
return err
280
}
260
- t.Cleanup(func() {
281
+ tc.t.Cleanup(func() {
282
os.Remove(f.Name())
283
})
263
- if _, err := f.WriteString(initConfig); err != nil {
284
+ if _, err := f.WriteString(fmt.Sprintf(initConfig, tc.config.AdminPort)); err != nil {
285
return err
286
}
287
@@ -271,23 +292,23 @@ func validateTestPrerequisites(t testing.TB) error {
292
}()
293
294
// wait for caddy to start serving the initial config
274
- for retries := 10; retries > 0 && isCaddyAdminRunning() != nil; retries-- {
295
+ for retries := 10; retries > 0 && isCaddyAdminRunning(tc) != nil; retries-- {
296
time.Sleep(1 * time.Second)
297
}
298
}
299
300
// one more time to return the error
280
- return isCaddyAdminRunning()
301
+ return isCaddyAdminRunning(tc)
302
}
303
283
-func isCaddyAdminRunning() error {
304
+func isCaddyAdminRunning(tc *Tester) error {
305
// assert that caddy is running
306
client := &http.Client{
286
- Timeout: Default.LoadRequestTimeout,
307
+ Timeout: tc.config.LoadRequestTimeout,
308
}
288
- resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", Default.AdminPort))
309
+ resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", tc.config.AdminPort))
310
if err != nil {
290
- return fmt.Errorf("caddy integration test caddy server not running. Expected to be listening on localhost:%d", Default.AdminPort)
311
+ return fmt.Errorf("caddy integration test caddy server not running. Expected to be listening on localhost:%d", tc.config.AdminPort)
312
}
313
resp.Body.Close()
314