@marcel91200 / caddy Mirror · read-only / commits / 8861eae2
Fork 0

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