From 3c591ecac96a4236d96dcb377ed542a818ff5165 Mon Sep 17 00:00:00 2001 From: a Date: Tue, 18 Jun 2024 23:45:54 -0500 Subject: [PATCH] noot --- caddytest/caddytest.go | 39 ++- caddytest/caddytest_test.go | 21 +- caddytest/integration/acme_test.go | 28 +- caddytest/integration/acmeserver_test.go | 49 +-- caddytest/integration/autohttps_test.go | 93 +++--- caddytest/integration/caddyfile_test.go | 301 ++++++++++-------- caddytest/integration/handler_test.go | 29 +- caddytest/integration/intercept_test.go | 21 +- caddytest/integration/leafcertloaders_test.go | 12 +- caddytest/integration/listener_test.go | 24 +- caddytest/integration/map_test.go | 61 ++-- caddytest/integration/reverseproxy_test.go | 92 +++--- caddytest/integration/sni_test.go | 46 +-- caddytest/integration/stream_test.go | 48 +-- caddytest/testing_harness.go | 4 + 15 files changed, 470 insertions(+), 398 deletions(-) diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 9a89d6b1..58cbfa06 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -13,6 +13,7 @@ import ( "os" "strconv" "strings" + "sync/atomic" "time" caddycmd "github.com/caddyserver/caddy/v2/cmd" @@ -42,7 +43,12 @@ var Default = Defaults{ type Tester struct { Client *http.Client - adminPort int + adminPort int + + portOne int + portTwo int + + started atomic.Bool configLoaded bool configFileName string envFileName string @@ -78,6 +84,9 @@ func timeElapsed(start time.Time, name string) { // launch caddy will start the server func (tc *Tester) LaunchCaddy() error { + if !tc.started.CompareAndSwap(false, true) { + return fmt.Errorf("already launched caddy with this tester") + } if err := tc.startServer(); err != nil { return fmt.Errorf("failed to start server: %w", err) } @@ -110,14 +119,32 @@ func (tc *Tester) CleanupCaddy() error { return fmt.Errorf("timed out waiting for caddytest server to stop") } +func (tc *Tester) AdminPort() int { + return tc.adminPort +} +func (tc *Tester) PortOne() int { + return tc.portOne +} +func (tc *Tester) PortTwo() int { + return tc.portTwo +} + +func (tc *Tester) ReplaceTestingPlaceholders(x string) string { + x = strings.ReplaceAll(x, "{$TESTING_CADDY_ADMIN_BIND}", fmt.Sprintf("localhost:%d", tc.adminPort)) + x = strings.ReplaceAll(x, "{$TESTING_CADDY_ADMIN_PORT}", fmt.Sprintf("%d", tc.adminPort)) + x = strings.ReplaceAll(x, "{$TESTING_CADDY_PORT_ONE}", fmt.Sprintf("%d", tc.portOne)) + x = strings.ReplaceAll(x, "{$TESTING_CADDY_PORT_TWO}", fmt.Sprintf("%d", tc.portTwo)) + return x +} + // LoadConfig loads the config to the tester server and also ensures that the config was loaded // it should not be run func (tc *Tester) LoadConfig(rawConfig string, configType string) error { if tc.adminPort == 0 { return fmt.Errorf("load config called where startServer didnt succeed") } + rawConfig = tc.ReplaceTestingPlaceholders(rawConfig) // replace special testing placeholders so we can have our admin api be on a random port - rawConfig = strings.ReplaceAll(rawConfig, "{$TESTING_ADMIN_API}", fmt.Sprintf("localhost:%d", tc.adminPort)) // normalize JSON config if configType == "json" { var conf any @@ -220,6 +247,14 @@ func (tc *Tester) startServer() error { return fmt.Errorf("could not find a open port to listen on: %w", err) } tc.adminPort = a + tc.portOne, err = getFreePort() + if err != nil { + return fmt.Errorf("could not find a open portOne: %w", err) + } + tc.portTwo, err = getFreePort() + if err != nil { + return fmt.Errorf("could not find a open portOne: %w", err) + } // setup the init config file, and set the cleanup afterwards { f, err := os.CreateTemp("", "") diff --git a/caddytest/caddytest_test.go b/caddytest/caddytest_test.go index 1cca9ff0..d788a810 100644 --- a/caddytest/caddytest_test.go +++ b/caddytest/caddytest_test.go @@ -1,13 +1,14 @@ package caddytest import ( + "fmt" "net/http" "strings" "testing" ) func TestReplaceCertificatePaths(t *testing.T) { - rawConfig := `a.caddy.localhost:9443 { + rawConfig := `a.caddy.localhost:9443{ tls /caddy.localhost.crt /caddy.localhost.key { } @@ -34,8 +35,8 @@ func TestReplaceCertificatePaths(t *testing.T) { } func TestLoadUnorderedJSON(t *testing.T) { - tester := StartHarness(t) - tester.LoadConfig(` + harness := StartHarness(t) + harness.LoadConfig(` { "logging": { "logs": { @@ -68,7 +69,7 @@ func TestLoadUnorderedJSON(t *testing.T) { } }, "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -79,13 +80,13 @@ func TestLoadUnorderedJSON(t *testing.T) { } }, "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "servers": { "s_server": { "listen": [ - ":9443", - ":9080" + ":{$TESTING_CADDY_PORT_ONE}", + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -120,10 +121,10 @@ func TestLoadUnorderedJSON(t *testing.T) { } } `, "json") - req, err := http.NewRequest(http.MethodGet, "http://localhost:9080/", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), nil) if err != nil { t.Fail() return } - tester.AssertResponseCode(req, 200) + harness.AssertResponseCode(req, 200) } diff --git a/caddytest/integration/acme_test.go b/caddytest/integration/acme_test.go index 8cd3220d..63cd1f81 100644 --- a/caddytest/integration/acme_test.go +++ b/caddytest/integration/acme_test.go @@ -24,13 +24,13 @@ const acmeChallengePort = 9081 // Test the basic functionality of Caddy's ACME server func TestACMEServerWithDefaults(t *testing.T) { ctx := context.Background() - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} local_certs } acme.localhost { @@ -41,8 +41,8 @@ func TestACMEServerWithDefaults(t *testing.T) { logger := caddy.Log().Named("acmeserver") client := acmez.Client{ Client: &acme.Client{ - Directory: "https://acme.localhost:9443/acme/local/directory", - HTTPClient: tester.Client(), + Directory: fmt.Sprintf("https://acme.localhost:%d/acme/local/directory", harness.Tester().PortTwo()), + HTTPClient: harness.Client(), Logger: logger, }, ChallengeSolvers: map[string]acmez.Solver{ @@ -92,13 +92,13 @@ func TestACMEServerWithMismatchedChallenges(t *testing.T) { ctx := context.Background() logger := caddy.Log().Named("acmez") - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} local_certs } acme.localhost { @@ -110,8 +110,8 @@ func TestACMEServerWithMismatchedChallenges(t *testing.T) { client := acmez.Client{ Client: &acme.Client{ - Directory: "https://acme.localhost:9443/acme/local/directory", - HTTPClient: tester.Client(), + Directory: fmt.Sprintf("https://acme.localhost:%d/acme/local/directory", harness.Tester().PortTwo()), + HTTPClient: harness.Client(), Logger: logger, }, ChallengeSolvers: map[string]acmez.Solver{ diff --git a/caddytest/integration/acmeserver_test.go b/caddytest/integration/acmeserver_test.go index 604a59f7..4c7946ac 100644 --- a/caddytest/integration/acmeserver_test.go +++ b/caddytest/integration/acmeserver_test.go @@ -5,6 +5,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "fmt" "strings" "testing" @@ -15,40 +16,40 @@ import ( ) func TestACMEServerDirectory(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust local_certs - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} pki { ca local { name "Caddy Local Authority" } } } - acme.localhost:9443 { + acme.localhost:{$TESTING_CADDY_PORT_TWO} { acme_server } `, "caddyfile") - tester.AssertGetResponse( - "https://acme.localhost:9443/acme/local/directory", + harness.AssertGetResponse( + fmt.Sprintf("https://acme.localhost:%d/acme/local/directory", harness.Tester().PortTwo()), 200, - `{"newNonce":"https://acme.localhost:9443/acme/local/new-nonce","newAccount":"https://acme.localhost:9443/acme/local/new-account","newOrder":"https://acme.localhost:9443/acme/local/new-order","revokeCert":"https://acme.localhost:9443/acme/local/revoke-cert","keyChange":"https://acme.localhost:9443/acme/local/key-change"} -`) + fmt.Sprintf(`{"newNonce":"https://acme.localhost:%[1]d/acme/local/new-nonce","newAccount":"https://acme.localhost:%[1]d/acme/local/new-account","newOrder":"https://acme.localhost:%[1]d/acme/local/new-order","revokeCert":"https://acme.localhost:%[1]d/acme/local/revoke-cert","keyChange":"https://acme.localhost:%[1]d/acme/local/key-change"} +`, harness.Tester().PortTwo())) } func TestACMEServerAllowPolicy(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust local_certs - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} pki { ca local { name "Caddy Local Authority" @@ -70,8 +71,8 @@ func TestACMEServerAllowPolicy(t *testing.T) { client := acmez.Client{ Client: &acme.Client{ - Directory: "https://acme.localhost:9443/acme/local/directory", - HTTPClient: tester.Client(), + Directory: fmt.Sprintf("https://acme.localhost:%d/acme/local/directory", harness.Tester().PortTwo()), + HTTPClient: harness.Client(), Logger: logger, }, ChallengeSolvers: map[string]acmez.Solver{ @@ -127,14 +128,14 @@ func TestACMEServerAllowPolicy(t *testing.T) { } func TestACMEServerDenyPolicy(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust local_certs - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} pki { ca local { name "Caddy Local Authority" @@ -155,8 +156,8 @@ func TestACMEServerDenyPolicy(t *testing.T) { client := acmez.Client{ Client: &acme.Client{ - Directory: "https://acme.localhost:9443/acme/local/directory", - HTTPClient: tester.Client(), + Directory: fmt.Sprintf("https://acme.localhost:%d/acme/local/directory", harness.Tester().PortTwo()), + HTTPClient: harness.Client(), Logger: logger, }, ChallengeSolvers: map[string]acmez.Solver{ diff --git a/caddytest/integration/autohttps_test.go b/caddytest/integration/autohttps_test.go index 89070b29..ec296400 100644 --- a/caddytest/integration/autohttps_test.go +++ b/caddytest/integration/autohttps_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "net/http" "testing" @@ -8,69 +9,69 @@ import ( ) func TestAutoHTTPtoHTTPSRedirectsImplicitPort(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} + admin {$TESTING_CADDY_ADMIN_BIND} skip_install_trust - http_port 9080 - https_port 9443 + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} } localhost respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + harness.AssertRedirect(fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), "https://localhost/", http.StatusPermanentRedirect) } func TestAutoHTTPtoHTTPSRedirectsExplicitPortSameAsHTTPSPort(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} } - localhost:9443 + localhost:{$TESTING_CADDY_PORT_TWO} respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + harness.AssertRedirect(fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), "https://localhost/", http.StatusPermanentRedirect) } func TestAutoHTTPtoHTTPSRedirectsExplicitPortDifferentFromHTTPSPort(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} } localhost:1234 respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost:1234/", http.StatusPermanentRedirect) + harness.AssertRedirect(fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), "https://localhost:1234/", http.StatusPermanentRedirect) } func TestAutoHTTPRedirectsWithHTTPListenerFirstInAddresses(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "servers": { "ingress_server": { "listen": [ - ":9080", - ":9443" + ":{$TESTING_CADDY_PORT_ONE}", + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -94,52 +95,52 @@ func TestAutoHTTPRedirectsWithHTTPListenerFirstInAddresses(t *testing.T) { } } `, "json") - tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + harness.AssertRedirect(fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), "https://localhost/", http.StatusPermanentRedirect) } func TestAutoHTTPRedirectsInsertedBeforeUserDefinedCatchAll(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} local_certs } - http://:9080 { + http://:{$TESTING_CADDY_PORT_ONE} { respond "Foo" } - http://baz.localhost:9080 { + http://baz.localhost:{$TESTING_CADDY_PORT_ONE} { respond "Baz" } bar.localhost { respond "Bar" } `, "caddyfile") - tester.AssertRedirect("http://bar.localhost:9080/", "https://bar.localhost/", http.StatusPermanentRedirect) - tester.AssertGetResponse("http://foo.localhost:9080/", 200, "Foo") - tester.AssertGetResponse("http://baz.localhost:9080/", 200, "Baz") + harness.AssertRedirect(fmt.Sprintf("http://bar.localhost:%d/", harness.Tester().PortOne()), "https://bar.localhost/", http.StatusPermanentRedirect) + harness.AssertGetResponse(fmt.Sprintf("http://foo.localhost:%d/", harness.Tester().PortOne()), 200, "Foo") + harness.AssertGetResponse(fmt.Sprintf("http://baz.localhost:%d/", harness.Tester().PortOne()), 200, "Baz") } func TestAutoHTTPRedirectsInsertedBeforeUserDefinedCatchAllWithNoExplicitHTTPSite(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} local_certs } - http://:9080 { + http://:{$TESTING_CADDY_PORT_ONE} { respond "Foo" } bar.localhost { respond "Bar" } `, "caddyfile") - tester.AssertRedirect("http://bar.localhost:9080/", "https://bar.localhost/", http.StatusPermanentRedirect) - tester.AssertGetResponse("http://foo.localhost:9080/", 200, "Foo") - tester.AssertGetResponse("http://baz.localhost:9080/", 200, "Foo") + harness.AssertRedirect(fmt.Sprintf("http://bar.localhost:%d/", harness.Tester().PortOne()), "https://bar.localhost/", http.StatusPermanentRedirect) + harness.AssertGetResponse(fmt.Sprintf("http://foo.localhost:%d/", harness.Tester().PortOne()), 200, "Foo") + harness.AssertGetResponse(fmt.Sprintf("http://baz.localhost:%d/", harness.Tester().PortOne()), 200, "Foo") } diff --git a/caddytest/integration/caddyfile_test.go b/caddytest/integration/caddyfile_test.go index 647d6b7c..dab5a7d1 100644 --- a/caddytest/integration/caddyfile_test.go +++ b/caddytest/integration/caddyfile_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "net/http" "net/url" "testing" @@ -10,16 +11,16 @@ import ( func TestRespond(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { respond /version 200 { body "hello from localhost" } @@ -27,23 +28,23 @@ func TestRespond(t *testing.T) { `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()), 200, "hello from localhost") } func TestRedirect(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { - redir / http://localhost:9080/hello 301 + redir / http://localhost:{$TESTING_CADDY_PORT_ONE}/hello 301 respond /hello 200 { body "hello from localhost" @@ -51,21 +52,22 @@ func TestRedirect(t *testing.T) { } `, "caddyfile") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) // act and assert - tester.AssertRedirect("http://localhost:9080/", "http://localhost:9080/hello", 301) + harness.AssertRedirect(target, target+"hello", 301) // follow redirect - tester.AssertGetResponse("http://localhost:9080/", 200, "hello from localhost") + harness.AssertGetResponse(target, 200, "hello from localhost") } func TestDuplicateHosts(t *testing.T) { // act and assert caddytest.AssertLoadError(t, ` - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { } `, "caddyfile", @@ -80,18 +82,18 @@ func TestReadCookie(t *testing.T) { } // arrange - tester := caddytest.StartHarness(t) - tester.Client().Jar.SetCookies(localhost, []*http.Cookie{&cookie}) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.Client().Jar.SetCookies(localhost, []*http.Cookie{&cookie}) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { templates { root testdata } @@ -102,21 +104,22 @@ func TestReadCookie(t *testing.T) { `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/cookie.html", 200, "

Cookie.ClientName caddytest

") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"cookie.html", 200, "

Cookie.ClientName caddytest

") } func TestReplIndex(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { templates { root testdata } @@ -128,7 +131,8 @@ func TestReplIndex(t *testing.T) { `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/", 200, "") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target, 200, "") } func TestInvalidPrefix(t *testing.T) { @@ -481,31 +485,32 @@ func TestValidPrefix(t *testing.T) { } func TestUriReplace(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri replace "\}" %7D uri replace "\{" %7B respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?test={%20content%20}", 200, "test=%7B%20content%20%7D") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?test={%20content%20}", 200, "test=%7B%20content%20%7D") } func TestUriOps(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query +foo bar uri query -baz uri query taz test @@ -514,7 +519,8 @@ func TestUriOps(t *testing.T) { respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar0&baz=buz&taz=nottest&changethis=val", 200, "changed=val&foo=bar0&foo=bar&key%3Dvalue=example&taz=test") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar0&baz=buz&taz=nottest&changethis=val", 200, "changed=val&foo=bar0&foo=bar&key%3Dvalue=example&taz=test") } // Tests the `http.request.local.port` placeholder. @@ -523,166 +529,176 @@ func TestUriOps(t *testing.T) { // refer to 127.0.0.1 or ::1. // TODO: Test each http version separately (especially http/3) func TestHttpRequestLocalPortPlaceholder(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} respond "{http.request.local.port}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/", 200, "9080") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target, 200, fmt.Sprintf("%d", harness.Tester().PortOne())) } func TestSetThenAddQueryParams(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo bar uri query +foo baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint", 200, "foo=bar&foo=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint", 200, "foo=bar&foo=baz") } func TestSetThenDeleteParams(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query bar foo{query.foo} uri query -foo respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar", 200, "bar=foobar") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar", 200, "bar=foobar") } func TestRenameAndOtherOps(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo>bar uri query bar taz uri query +bar baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar", 200, "bar=taz&bar=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar", 200, "bar=taz&bar=baz") } func TestReplaceOps(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo bar baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar", 200, "foo=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar", 200, "foo=baz") } func TestReplaceWithReplacementPlaceholder(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo bar {query.placeholder} respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?placeholder=baz&foo=bar", 200, "foo=baz&placeholder=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?placeholder=baz&foo=bar", 200, "foo=baz&placeholder=baz") } func TestReplaceWithKeyPlaceholder(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query {query.placeholder} bar baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?placeholder=foo&foo=bar", 200, "foo=baz&placeholder=foo") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?placeholder=foo&foo=bar", 200, "foo=baz&placeholder=foo") } func TestPartialReplacement(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo ar az respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar", 200, "foo=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar", 200, "foo=baz") } func TestNonExistingSearch(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query foo var baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar", 200, "foo=bar") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar", 200, "foo=bar") } func TestReplaceAllOps(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query * bar baz respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar&baz=bar", 200, "baz=baz&foo=baz") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar&baz=bar", 200, "baz=baz&foo=baz") } func TestUriOpsBlock(t *testing.T) { - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) - tester.LoadConfig(` + harness.LoadConfig(` { - admin {$TESTING_ADMIN_API} - http_port 9080 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - :9080 + :{$TESTING_CADDY_PORT_ONE} uri query { +foo bar -baz @@ -690,16 +706,17 @@ func TestUriOpsBlock(t *testing.T) { } respond "{query}"`, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/endpoint?foo=bar0&baz=buz&taz=nottest", 200, "foo=bar0&foo=bar&taz=test") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"endpoint?foo=bar0&baz=buz&taz=nottest", 200, "foo=bar0&foo=bar&taz=test") } func TestHandleErrorSimpleCodes(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ - admin {$TESTING_ADMIN_API} - http_port 9080 + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { root * /srv error /private* "Unauthorized" 410 error /hidden* "Not found" 404 @@ -709,17 +726,18 @@ func TestHandleErrorSimpleCodes(t *testing.T) { } }`, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/private", 410, "404 or 410 error") - tester.AssertGetResponse("http://localhost:9080/hidden", 404, "404 or 410 error") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"private", 410, "404 or 410 error") + harness.AssertGetResponse(target+"hidden", 404, "404 or 410 error") } func TestHandleErrorRange(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ - admin {$TESTING_ADMIN_API} - http_port 9080 + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { root * /srv error /private* "Unauthorized" 410 error /hidden* "Not found" 404 @@ -729,17 +747,18 @@ func TestHandleErrorRange(t *testing.T) { } }`, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/private", 410, "Error in the [400 .. 499] range") - tester.AssertGetResponse("http://localhost:9080/hidden", 404, "Error in the [400 .. 499] range") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"private", 410, "Error in the [400 .. 499] range") + harness.AssertGetResponse(target+"hidden", 404, "Error in the [400 .. 499] range") } func TestHandleErrorSort(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ - admin {$TESTING_ADMIN_API} - http_port 9080 + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { root * /srv error /private* "Unauthorized" 410 error /hidden* "Not found" 404 @@ -753,17 +772,18 @@ func TestHandleErrorSort(t *testing.T) { } }`, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/internalerr", 500, "Fallback route: code outside the [400..499] range") - tester.AssertGetResponse("http://localhost:9080/hidden", 404, "Error in the [400 .. 499] range") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"internalerr", 500, "Fallback route: code outside the [400..499] range") + harness.AssertGetResponse(target+"hidden", 404, "Error in the [400 .. 499] range") } func TestHandleErrorRangeAndCodes(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ - admin {$TESTING_ADMIN_API} - http_port 9080 + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { root * /srv error /private* "Unauthorized" 410 error /threehundred* "Moved Permanently" 301 @@ -777,9 +797,10 @@ func TestHandleErrorRangeAndCodes(t *testing.T) { } }`, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/internalerr", 500, "Error code is equal to 500 or in the [300..399] range") - tester.AssertGetResponse("http://localhost:9080/threehundred", 301, "Error code is equal to 500 or in the [300..399] range") - tester.AssertGetResponse("http://localhost:9080/private", 410, "Error in the [400 .. 499] range") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target+"internalerr", 500, "Error code is equal to 500 or in the [300..399] range") + harness.AssertGetResponse(target+"threehundred", 301, "Error code is equal to 500 or in the [300..399] range") + harness.AssertGetResponse(target+"private", 410, "Error in the [400 .. 499] range") } func TestInvalidSiteAddressesAsDirectives(t *testing.T) { diff --git a/caddytest/integration/handler_test.go b/caddytest/integration/handler_test.go index 11d85242..500c0e44 100644 --- a/caddytest/integration/handler_test.go +++ b/caddytest/integration/handler_test.go @@ -2,6 +2,7 @@ package integration import ( "bytes" + "fmt" "net/http" "testing" @@ -9,36 +10,36 @@ import ( ) func TestBrowse(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - http://localhost:9080 { + http://localhost:{$TESTING_CADDY_PORT_ONE} { file_server browse } `, "caddyfile") - req, err := http.NewRequest(http.MethodGet, "http://localhost:9080/", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), nil) if err != nil { t.Fail() return } - tester.AssertResponseCode(req, 200) + harness.AssertResponseCode(req, 200) } func TestRespondWithJSON(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } localhost { @@ -46,7 +47,7 @@ func TestRespondWithJSON(t *testing.T) { } `, "caddyfile") - res, _ := tester.AssertPostResponseBody("https://localhost:9443/", + res, _ := harness.AssertPostResponseBody(fmt.Sprintf("https://localhost:%d/", harness.Tester().PortTwo()), nil, bytes.NewBufferString(`{ "greeting": "Hello, world!" diff --git a/caddytest/integration/intercept_test.go b/caddytest/integration/intercept_test.go index 2e4d780c..f52ac5ff 100644 --- a/caddytest/integration/intercept_test.go +++ b/caddytest/integration/intercept_test.go @@ -1,22 +1,23 @@ package integration import ( + "fmt" "testing" "github.com/caddyserver/caddy/v2/caddytest" ) func TestIntercept(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - - localhost:9080 { + + localhost:{$TESTING_CADDY_PORT_ONE} { respond /intercept "I'm a teapot" 408 respond /no-intercept "I'm not a teapot" @@ -25,10 +26,10 @@ func TestIntercept(t *testing.T) { handle_response @teapot { respond /intercept "I'm a combined coffee/tea pot that is temporarily out of coffee" 503 } - } + } } `, "caddyfile") - tester.AssertGetResponse("http://localhost:9080/intercept", 503, "I'm a combined coffee/tea pot that is temporarily out of coffee") - tester.AssertGetResponse("http://localhost:9080/no-intercept", 200, "I'm not a teapot") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/intercept", harness.Tester().PortOne()), 503, "I'm a combined coffee/tea pot that is temporarily out of coffee") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/no-intercept", harness.Tester().PortOne()), 200, "I'm not a teapot") } diff --git a/caddytest/integration/leafcertloaders_test.go b/caddytest/integration/leafcertloaders_test.go index 90c396f4..502674ed 100644 --- a/caddytest/integration/leafcertloaders_test.go +++ b/caddytest/integration/leafcertloaders_test.go @@ -7,21 +7,21 @@ import ( ) func TestLeafCertLoaders(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { diff --git a/caddytest/integration/listener_test.go b/caddytest/integration/listener_test.go index 24b86509..f22f5133 100644 --- a/caddytest/integration/listener_test.go +++ b/caddytest/integration/listener_test.go @@ -28,15 +28,15 @@ func setupListenerWrapperTest(t *testing.T, handlerFunc http.HandlerFunc) *caddy _ = srv.Close() _ = l.Close() }) - tester := caddytest.StartHarness(t) - tester.LoadConfig(fmt.Sprintf(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(fmt.Sprintf(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} local_certs - servers :9443 { + servers :{$TESTING_CADDY_PORT_TWO} { listener_wrappers { http_redirect tls @@ -47,7 +47,7 @@ func setupListenerWrapperTest(t *testing.T, handlerFunc http.HandlerFunc) *caddy reverse_proxy %s } `, l.Addr().String()), "caddyfile") - return tester + return harness } func TestHTTPRedirectWrapperWithLargeUpload(t *testing.T) { @@ -56,7 +56,7 @@ func TestHTTPRedirectWrapperWithLargeUpload(t *testing.T) { body := make([]byte, uploadSize) rand.New(rand.NewSource(0)).Read(body) - tester := setupListenerWrapperTest(t, func(writer http.ResponseWriter, request *http.Request) { + harness := setupListenerWrapperTest(t, func(writer http.ResponseWriter, request *http.Request) { buf := new(bytes.Buffer) _, err := buf.ReadFrom(request.Body) if err != nil { @@ -69,7 +69,7 @@ func TestHTTPRedirectWrapperWithLargeUpload(t *testing.T) { writer.WriteHeader(http.StatusNoContent) }) - resp, err := tester.Client().Post("https://localhost:9443", "application/octet-stream", bytes.NewReader(body)) + resp, err := harness.Client().Post(fmt.Sprintf("https://localhost:%d", harness.Tester().PortTwo()), "application/octet-stream", bytes.NewReader(body)) if err != nil { t.Fatalf("failed to post: %s", err) } @@ -80,14 +80,14 @@ func TestHTTPRedirectWrapperWithLargeUpload(t *testing.T) { } func TestLargeHttpRequest(t *testing.T) { - tester := setupListenerWrapperTest(t, func(writer http.ResponseWriter, request *http.Request) { + harness := setupListenerWrapperTest(t, func(writer http.ResponseWriter, request *http.Request) { t.Fatal("not supposed to handle a request") }) // We never read the body in any way, set an extra long header instead. - req, _ := http.NewRequest("POST", "http://localhost:9443", nil) + req, _ := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d", harness.Tester().PortTwo()), nil) req.Header.Set("Long-Header", strings.Repeat("X", 1024*1024)) - _, err := tester.Client().Do(req) + _, err := harness.Client().Do(req) if err == nil { t.Fatal("not supposed to succeed") } diff --git a/caddytest/integration/map_test.go b/caddytest/integration/map_test.go index ac20af45..88ceb9e3 100644 --- a/caddytest/integration/map_test.go +++ b/caddytest/integration/map_test.go @@ -2,6 +2,7 @@ package integration import ( "bytes" + "fmt" "testing" "github.com/caddyserver/caddy/v2/caddytest" @@ -9,16 +10,16 @@ import ( func TestMap(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - localhost:9080 { + localhost:{$TESTING_CADDY_PORT_ONE} { map {http.request.method} {dest-1} {dest-2} { default unknown1 unknown2 @@ -28,50 +29,50 @@ func TestMap(t *testing.T) { respond /version 200 { body "hello from localhost {dest-1} {dest-2}" - } + } } `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost GET-called unknown2") - tester.AssertPostResponseBody("http://localhost:9080/version", []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost post-called foobar") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()), 200, "hello from localhost GET-called unknown2") + harness.AssertPostResponseBody(fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()), []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost post-called foobar") } func TestMapRespondWithDefault(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} } - - localhost:9080 { - + + localhost:{$TESTING_CADDY_PORT_ONE} { + map {http.request.method} {dest-name} { default unknown GET get-called } - + respond /version 200 { body "hello from localhost {dest-name}" - } + } } `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost get-called") - tester.AssertPostResponseBody("http://localhost:9080/version", []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost unknown") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()), 200, "hello from localhost get-called") + harness.AssertPostResponseBody(fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()), []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost unknown") } func TestMapAsJSON(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -82,12 +83,12 @@ func TestMapAsJSON(t *testing.T) { } }, "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "servers": { "srv0": { "listen": [ - ":9080" + ":{$TESTING_CADDY_PORT_ONE}" ], "routes": [ { @@ -145,7 +146,7 @@ func TestMapAsJSON(t *testing.T) { } } }`, "json") - - tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost get-called") - tester.AssertPostResponseBody("http://localhost:9080/version", []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost post-called") + target := fmt.Sprintf("http://localhost:%d/version", harness.Tester().PortOne()) + harness.AssertGetResponse(target, 200, "hello from localhost get-called") + harness.AssertPostResponseBody(target, []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost post-called") } diff --git a/caddytest/integration/reverseproxy_test.go b/caddytest/integration/reverseproxy_test.go index fdb742e8..f141f613 100644 --- a/caddytest/integration/reverseproxy_test.go +++ b/caddytest/integration/reverseproxy_test.go @@ -14,11 +14,11 @@ import ( ) func TestSRVReverseProxy(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -87,11 +87,11 @@ func TestDialWithPlaceholderUnix(t *testing.T) { }) runtime.Gosched() // Allow other goroutines to run - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -135,15 +135,15 @@ func TestDialWithPlaceholderUnix(t *testing.T) { return } req.Header.Set("X-Caddy-Upstream-Dial", socketName) - tester.AssertResponse(req, 200, "Hello, World!") + harness.AssertResponse(req, 200, "Hello, World!") } func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -186,7 +186,7 @@ func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { }, "srv1": { "listen": [ - ":9080" + ":{$TESTING_CADDY_PORT_ONE}" ], "routes": [ { @@ -199,7 +199,7 @@ func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { ], "handle": [ { - + "handler": "reverse_proxy", "upstreams": [ { @@ -223,21 +223,21 @@ func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { } `, "json") - req, err := http.NewRequest(http.MethodGet, "http://localhost:9080", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%d", harness.Tester().PortOne()), nil) if err != nil { t.Fail() return } req.Header.Set("X-Caddy-Upstream-Dial", "localhost:18080") - tester.AssertResponse(req, 200, "Hello, World!") + harness.AssertResponse(req, 200, "Hello, World!") } func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "pki": { @@ -280,7 +280,7 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { }, "srv1": { "listen": [ - ":9080" + ":{$TESTING_CADDY_PORT_ONE}" ], "routes": [ { @@ -293,7 +293,7 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { ], "handle": [ { - + "handler": "reverse_proxy", "upstreams": [ { @@ -317,23 +317,23 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { } `, "json") - req, err := http.NewRequest(http.MethodGet, "http://localhost:9080", nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%d", harness.Tester().PortOne()), nil) if err != nil { t.Fail() return } req.Header.Set("X-Caddy-Upstream-Dial", "localhost") - tester.AssertResponse(req, 200, "Hello, World!") + harness.AssertResponse(req, 200, "Hello, World!") } func TestReverseProxyHealthCheck(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } http://localhost:2020 { @@ -342,10 +342,10 @@ func TestReverseProxyHealthCheck(t *testing.T) { http://localhost:2021 { respond "ok" } - http://localhost:9080 { + http://localhost:{$TESTING_CADDY_PORT_ONE} { reverse_proxy { to localhost:2020 - + health_uri /health health_port 2021 health_interval 10ms @@ -357,14 +357,15 @@ func TestReverseProxyHealthCheck(t *testing.T) { `, "caddyfile") time.Sleep(100 * time.Millisecond) // TODO: for some reason this test seems particularly flaky, getting 503 when it should be 200, unless we wait - tester.AssertGetResponse("http://localhost:9080/", 200, "Hello, World!") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target, 200, "Hello, World!") } func TestReverseProxyHealthCheckUnixSocket(t *testing.T) { if runtime.GOOS == "windows" { t.SkipNow() } - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) f, err := os.CreateTemp("", "*.sock") if err != nil { t.Errorf("failed to create TempFile: %s", err) @@ -395,18 +396,18 @@ func TestReverseProxyHealthCheckUnixSocket(t *testing.T) { }) runtime.Gosched() // Allow other goroutines to run - tester.LoadConfig(fmt.Sprintf(` + harness.LoadConfig(fmt.Sprintf(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - http://localhost:9080 { + http://localhost:{$TESTING_CADDY_PORT_ONE} { reverse_proxy { to unix/%s - + health_uri /health health_port 2021 health_interval 2s @@ -415,14 +416,15 @@ func TestReverseProxyHealthCheckUnixSocket(t *testing.T) { } `, socketName), "caddyfile") - tester.AssertGetResponse("http://localhost:9080/", 200, "Hello, World!") + target := fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()) + harness.AssertGetResponse(target, 200, "Hello, World!") } func TestReverseProxyHealthCheckUnixSocketWithoutPort(t *testing.T) { if runtime.GOOS == "windows" { t.SkipNow() } - tester := caddytest.StartHarness(t) + harness := caddytest.StartHarness(t) f, err := os.CreateTemp("", "*.sock") if err != nil { t.Errorf("failed to create TempFile: %s", err) @@ -453,18 +455,18 @@ func TestReverseProxyHealthCheckUnixSocketWithoutPort(t *testing.T) { }) runtime.Gosched() // Allow other goroutines to run - tester.LoadConfig(fmt.Sprintf(` + harness.LoadConfig(fmt.Sprintf(` { skip_install_trust - admin {$TESTING_ADMIN_API} - http_port 9080 - https_port 9443 + admin {$TESTING_CADDY_ADMIN_BIND} + http_port {$TESTING_CADDY_PORT_ONE} + https_port {$TESTING_CADDY_PORT_TWO} grace_period 1ns } - http://localhost:9080 { + http://localhost:{$TESTING_CADDY_PORT_ONE} { reverse_proxy { to unix/%s - + health_uri /health health_interval 2s health_timeout 5s @@ -472,5 +474,5 @@ func TestReverseProxyHealthCheckUnixSocketWithoutPort(t *testing.T) { } `, socketName), "caddyfile") - tester.AssertGetResponse("http://localhost:9080/", 200, "Hello, World!") + harness.AssertGetResponse(fmt.Sprintf("http://localhost:%d/", harness.Tester().PortOne()), 200, "Hello, World!") } diff --git a/caddytest/integration/sni_test.go b/caddytest/integration/sni_test.go index e5aced6e..8a5cfb73 100644 --- a/caddytest/integration/sni_test.go +++ b/caddytest/integration/sni_test.go @@ -1,6 +1,7 @@ package integration import ( + "fmt" "testing" "github.com/caddyserver/caddy/v2/caddytest" @@ -8,20 +9,20 @@ import ( func TestDefaultSNI(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(`{ + harness := caddytest.StartHarness(t) + harness.LoadConfig(`{ "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -102,26 +103,27 @@ func TestDefaultSNI(t *testing.T) { // act and assert // makes a request with no sni - tester.AssertGetResponse("https://127.0.0.1:9443/version", 200, "hello from a.caddy.localhost") + target := fmt.Sprintf("https://127.0.0.1:%d/", harness.Tester().PortTwo()) + harness.AssertGetResponse(target+"version", 200, "hello from a.caddy.localhost") } func TestDefaultSNIWithNamedHostAndExplicitIP(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -206,26 +208,27 @@ func TestDefaultSNIWithNamedHostAndExplicitIP(t *testing.T) { // act and assert // makes a request with no sni - tester.AssertGetResponse("https://127.0.0.1:9443/version", 200, "hello from a") + target := fmt.Sprintf("https://127.0.0.1:%d/", harness.Tester().PortTwo()) + harness.AssertGetResponse(target+"version", 200, "hello from a") } func TestDefaultSNIWithPortMappingOnly(t *testing.T) { // arrange - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -282,7 +285,8 @@ func TestDefaultSNIWithPortMappingOnly(t *testing.T) { // act and assert // makes a request with no sni - tester.AssertGetResponse("https://127.0.0.1:9443/version", 200, "hello from a.caddy.localhost") + target := fmt.Sprintf("https://127.0.0.1:%d/", harness.Tester().PortTwo()) + harness.AssertGetResponse(target+"version", 200, "hello from a.caddy.localhost") } func TestHttpOnlyOnDomainWithSNI(t *testing.T) { diff --git a/caddytest/integration/stream_test.go b/caddytest/integration/stream_test.go index e4769779..e23c4f3d 100644 --- a/caddytest/integration/stream_test.go +++ b/caddytest/integration/stream_test.go @@ -20,21 +20,21 @@ import ( // (see https://github.com/caddyserver/caddy/issues/3556 for use case) func TestH2ToH2CStream(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, - "grace_period": 1, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, + "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -102,7 +102,7 @@ func TestH2ToH2CStream(t *testing.T) { expectedBody := "some data to be echoed" // start the server - server := testH2ToH2CStreamServeH2C(t) + server := testH2ToH2CStreamServeH2C(harness, t) go server.ListenAndServe() defer func() { ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) @@ -116,7 +116,7 @@ func TestH2ToH2CStream(t *testing.T) { Body: io.NopCloser(r), URL: &url.URL{ Scheme: "https", - Host: "127.0.0.1:9443", + Host: fmt.Sprintf("127.0.0.1:%d", harness.Tester().PortTwo()), Path: "/tov2ray", }, Proto: "HTTP/2", @@ -127,7 +127,7 @@ func TestH2ToH2CStream(t *testing.T) { // Disable any compression method from server. req.Header.Set("Accept-Encoding", "identity") - resp := tester.AssertResponseCode(req, http.StatusOK) + resp := harness.AssertResponseCode(req, http.StatusOK) if resp.StatusCode != http.StatusOK { return } @@ -149,7 +149,7 @@ func TestH2ToH2CStream(t *testing.T) { } } -func testH2ToH2CStreamServeH2C(t *testing.T) *http.Server { +func testH2ToH2CStreamServeH2C(harness *caddytest.TestHarness, t *testing.T) *http.Server { h2s := &http2.Server{} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rstring, err := httputil.DumpRequest(r, false) @@ -163,7 +163,7 @@ func testH2ToH2CStreamServeH2C(t *testing.T) *http.Server { return } - if r.Host != "127.0.0.1:9443" { + if r.Host != fmt.Sprintf("127.0.0.1:%d", harness.Tester().PortTwo()) { t.Errorf("r.Host doesn't match, %v!", r.Host) w.WriteHeader(http.StatusNotFound) return @@ -204,21 +204,21 @@ func testH2ToH2CStreamServeH2C(t *testing.T) *http.Server { // (see https://github.com/caddyserver/caddy/issues/3606 for use case) func TestH2ToH1ChunkedResponse(t *testing.T) { - tester := caddytest.StartHarness(t) - tester.LoadConfig(` + harness := caddytest.StartHarness(t) + harness.LoadConfig(` { "admin": { - "listen": "{$TESTING_ADMIN_API}" + "listen": "{$TESTING_CADDY_ADMIN_BIND}" }, "apps": { "http": { - "http_port": 9080, - "https_port": 9443, - "grace_period": 1, + "http_port": {$TESTING_CADDY_PORT_ONE}, + "https_port": {$TESTING_CADDY_PORT_TWO}, + "grace_period": 1, "servers": { "srv0": { "listen": [ - ":9443" + ":{$TESTING_CADDY_PORT_TWO}" ], "routes": [ { @@ -305,7 +305,7 @@ func TestH2ToH1ChunkedResponse(t *testing.T) { } // start the server - server := testH2ToH1ChunkedResponseServeH1(t) + server := testH2ToH1ChunkedResponseServeH1(harness, t) go server.ListenAndServe() defer func() { ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) @@ -319,7 +319,7 @@ func TestH2ToH1ChunkedResponse(t *testing.T) { Body: io.NopCloser(r), URL: &url.URL{ Scheme: "https", - Host: "127.0.0.1:9443", + Host: fmt.Sprintf("127.0.0.1:%d", harness.Tester().PortTwo()), Path: "/tov2ray", }, Proto: "HTTP/2", @@ -333,7 +333,7 @@ func TestH2ToH1ChunkedResponse(t *testing.T) { fmt.Fprint(w, expectedBody) w.Close() }() - resp := tester.AssertResponseCode(req, http.StatusOK) + resp := harness.AssertResponseCode(req, http.StatusOK) if resp.StatusCode != http.StatusOK { return } @@ -351,9 +351,9 @@ func TestH2ToH1ChunkedResponse(t *testing.T) { } } -func testH2ToH1ChunkedResponseServeH1(t *testing.T) *http.Server { +func testH2ToH1ChunkedResponseServeH1(harness *caddytest.TestHarness, t *testing.T) *http.Server { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Host != "127.0.0.1:9443" { + if r.Host != fmt.Sprintf("127.0.0.1:%d", harness.Tester().PortTwo()) { t.Errorf("r.Host doesn't match, %v!", r.Host) w.WriteHeader(http.StatusNotFound) return diff --git a/caddytest/testing_harness.go b/caddytest/testing_harness.go index c5af3f6f..c9d7a70f 100644 --- a/caddytest/testing_harness.go +++ b/caddytest/testing_harness.go @@ -55,6 +55,10 @@ func StartHarness(t *testing.T) *TestHarness { return o } +func (tc *TestHarness) Tester() *Tester { + return tc.tester +} + func (tc *TestHarness) Client() *http.Client { return tc.tester.Client }