Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 50 additions & 51 deletions caddy/caddy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,25 @@ import (
"github.com/stretchr/testify/require"
)

// waitForServerReady polls the server with retries until it responds to HTTP requests.
// This handles a race condition during Caddy config reload on macOS where SO_REUSEPORT
// can briefly route connections to the old listener being shut down,
// initServer initializes a Caddy test server and waits for it to be ready.
// After InitServer, it polls the server to handle a race condition on macOS where
// SO_REUSEPORT can briefly route connections to the old listener being shut down,
// resulting in "connection reset by peer".
func waitForServerReady(t *testing.T, url string) {
func initServer(t *testing.T, tester *caddytest.Tester, config string, format string) {
t.Helper()
tester.InitServer(config, format)

client := &http.Client{Timeout: 1 * time.Second}
for range 10 {
resp, err := client.Get(url)
if err == nil {
require.NoError(t, resp.Body.Close())

return
require.Eventually(t, func() bool {
resp, err := client.Get("http://localhost:" + testPort)
if err != nil {
return false
}

time.Sleep(100 * time.Millisecond)
}
require.NoError(t, resp.Body.Close())

return true
}, 5*time.Second, 100*time.Millisecond, "server failed to become ready")
}

var testPort = "9080"
Expand Down Expand Up @@ -74,7 +75,7 @@ func TestMain(m *testing.M) {
func TestPHP(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -104,7 +105,7 @@ func TestPHP(t *testing.T) {

func TestLargeRequest(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -133,7 +134,7 @@ func TestLargeRequest(t *testing.T) {
func TestWorker(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -170,7 +171,7 @@ func TestGlobalAndModuleWorker(t *testing.T) {
testPortNum, _ := strconv.Atoi(testPort)
testPortTwo := strconv.Itoa(testPortNum + 1)
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -220,7 +221,7 @@ func TestGlobalAndModuleWorker(t *testing.T) {

func TestModuleWorkerInheritsEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand All @@ -245,7 +246,7 @@ func TestNamedModuleWorkers(t *testing.T) {
testPortNum, _ := strconv.Atoi(testPort)
testPortTwo := strconv.Itoa(testPortNum + 1)
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -294,7 +295,7 @@ func TestNamedModuleWorkers(t *testing.T) {

func TestEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -325,7 +326,7 @@ func TestEnv(t *testing.T) {

func TestJsonEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
"admin": {
"listen": "localhost:2999"
Expand Down Expand Up @@ -408,7 +409,7 @@ func TestJsonEnv(t *testing.T) {

func TestCustomCaddyVariablesInEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -442,7 +443,7 @@ func TestCustomCaddyVariablesInEnv(t *testing.T) {

func TestPHPServerDirective(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand All @@ -456,15 +457,14 @@ func TestPHPServerDirective(t *testing.T) {
}
`, "caddyfile")

waitForServerReady(t, "http://localhost:"+testPort)
tester.AssertGetResponse("http://localhost:"+testPort, http.StatusOK, "I am by birth a Genevese (i not set)")
tester.AssertGetResponse("http://localhost:"+testPort+"/hello.txt", http.StatusOK, "Hello\n")
tester.AssertGetResponse("http://localhost:"+testPort+"/not-found.txt", http.StatusOK, "I am by birth a Genevese (i not set)")
}

func TestPHPServerDirectiveDisableFileServer(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand All @@ -482,15 +482,14 @@ func TestPHPServerDirectiveDisableFileServer(t *testing.T) {
}
`, "caddyfile")

waitForServerReady(t, "http://localhost:"+testPort)
tester.AssertGetResponse("http://localhost:"+testPort, http.StatusOK, "I am by birth a Genevese (i not set)")
tester.AssertGetResponse("http://localhost:"+testPort+"/not-found.txt", http.StatusOK, "I am by birth a Genevese (i not set)")
}

func TestMetrics(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -571,7 +570,7 @@ func TestMetrics(t *testing.T) {
func TestWorkerMetrics(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -672,7 +671,7 @@ func TestWorkerMetrics(t *testing.T) {
func TestNamedWorkerMetrics(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -767,7 +766,7 @@ func TestNamedWorkerMetrics(t *testing.T) {
func TestAutoWorkerConfig(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -868,7 +867,7 @@ func TestAllDefinedServerVars(t *testing.T) {
expectedBody = strings.ReplaceAll(expectedBody, "{testPort}", testPort)
expectedBody = strings.ReplaceAll(expectedBody, documentRoot+"/", documentRoot+string(filepath.Separator))
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -900,7 +899,7 @@ func TestAllDefinedServerVars(t *testing.T) {

func TestPHPIniConfiguration(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -928,7 +927,7 @@ func TestPHPIniConfiguration(t *testing.T) {

func TestPHPIniBlockConfiguration(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -968,7 +967,7 @@ func testSingleIniConfiguration(tester *caddytest.Tester, key string, value stri

func TestOsEnv(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -998,7 +997,7 @@ func TestOsEnv(t *testing.T) {

func TestMaxWaitTime(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1039,7 +1038,7 @@ func TestMaxWaitTime(t *testing.T) {

func TestMaxWaitTimeWorker(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1122,7 +1121,7 @@ func getStatusCode(url string, t *testing.T) int {
func TestMultiWorkersMetrics(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1231,7 +1230,7 @@ func TestMultiWorkersMetrics(t *testing.T) {
func TestDisabledMetrics(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1311,7 +1310,7 @@ func TestDisabledMetrics(t *testing.T) {
func TestWorkerRestart(t *testing.T) {
var wg sync.WaitGroup
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1413,7 +1412,7 @@ func TestWorkerRestart(t *testing.T) {

func TestWorkerMatchDirective(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1446,7 +1445,7 @@ func TestWorkerMatchDirective(t *testing.T) {

func TestWorkerMatchDirectiveWithMultipleWorkers(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1487,7 +1486,7 @@ func TestWorkerMatchDirectiveWithMultipleWorkers(t *testing.T) {

func TestWorkerMatchDirectiveWithoutFileServer(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1520,7 +1519,7 @@ func TestWorkerMatchDirectiveWithoutFileServer(t *testing.T) {

func TestDd(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand All @@ -1544,7 +1543,7 @@ func TestDd(t *testing.T) {

func TestLog(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1582,7 +1581,7 @@ func TestSymlinkWorkerPaths(t *testing.T) {
// When I execute `frankenphp php-server --listen localhost:8080 -w index.php` from `public`
// Then I expect to see the worker script executed successfully
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1612,7 +1611,7 @@ func TestSymlinkWorkerPaths(t *testing.T) {
// When I execute `frankenphp --listen localhost:8080 -w nested/index.php` from `public`
// Then I expect to see the worker script executed successfully
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1642,7 +1641,7 @@ func TestSymlinkWorkerPaths(t *testing.T) {
// When I execute `frankenphp --listen localhost:8080 -w public/index.php` from the root folder
// Then I expect to see the worker script executed successfully
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1676,7 +1675,7 @@ func TestSymlinkWorkerPaths(t *testing.T) {
// When I execute `frankenphp --listen localhost:8080 -w public/index.php -r public` from the root folder
// Then I expect to see the worker script executed successfully
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1715,7 +1714,7 @@ func TestSymlinkResolveRoot(t *testing.T) {
t.Run("ResolveRootSymlink", func(t *testing.T) {
// Tests that resolve_root_symlink directive works correctly
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1743,7 +1742,7 @@ func TestSymlinkResolveRoot(t *testing.T) {
t.Run("NoResolveRootSymlink", func(t *testing.T) {
// Tests that symlinks are preserved when resolve_root_symlink is false (non-worker mode)
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down Expand Up @@ -1774,7 +1773,7 @@ func TestSymlinkWorkerBehavior(t *testing.T) {
t.Run("WorkerScriptFailsWithoutWorkerMode", func(t *testing.T) {
// Tests that accessing a worker-only script without configuring it as a worker actually results in an error
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand All @@ -1798,7 +1797,7 @@ func TestSymlinkWorkerBehavior(t *testing.T) {
t.Run("MultipleRequests", func(t *testing.T) {
// Tests that symlinked workers handle multiple requests correctly
tester := caddytest.NewTester(t)
tester.InitServer(`
initServer(t, tester, `
{
skip_install_trust
admin localhost:2999
Expand Down