This commit is contained in:
a 2024-06-18 20:08:38 -05:00
parent b98c89fbb6
commit 01cb878087
No known key found for this signature in database
GPG key ID: 374BC539FE795AF0
4 changed files with 37 additions and 61 deletions

View file

@ -780,7 +780,7 @@ func exitProcess(ctx context.Context, logger *zap.Logger) {
logger.Error("unclean shutdown")
}
// check if we are in test environment, and dont call exit if we are
if flag.Lookup("test.v") == nil || strings.Contains(os.Args[0], ".test") {
if flag.Lookup("test.v") == nil || !strings.Contains(os.Args[0], ".test") {
os.Exit(exitCode)
}
}()

View file

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"log"
@ -12,15 +11,11 @@ import (
"net/http"
"net/http/cookiejar"
"os"
"path"
"reflect"
"runtime"
"strings"
"time"
caddycmd "github.com/caddyserver/caddy/v2/cmd"
"github.com/caddyserver/caddy/v2/caddyconfig"
// plug in Caddy modules here
_ "github.com/caddyserver/caddy/v2/modules/standard"
)
@ -96,7 +91,7 @@ func (tc *Tester) CleanupCaddy() error {
}()
_, err := http.Post(fmt.Sprintf("http://localhost:%d/stop", Default.AdminPort), "", nil)
if err != nil {
return fmt.Errorf("couldn't stop caddytest server")
return fmt.Errorf("couldn't stop caddytest server: %w", err)
}
time.Sleep(200 * time.Millisecond)
for retries := 0; retries < 10; retries++ {
@ -112,7 +107,6 @@ func (tc *Tester) CleanupCaddy() error {
// LoadConfig loads the config to the tester server and also ensures that the config was loaded
func (tc *Tester) LoadConfig(rawConfig string, configType string) error {
originalRawConfig := rawConfig
// normalize JSON config
if configType == "json" {
var conf any
@ -157,56 +151,32 @@ func (tc *Tester) LoadConfig(rawConfig string, configType string) error {
}
tc.configLoaded = true
return tc.ensureConfigRunning(originalRawConfig, configType)
// if the config is not loaded at this point, it is a bug in caddy's config.Load
// the contract for config.Load states that the config must be loaded before it returns, and that it will
// error if the config fails to apply
return nil
}
func (tc *Tester) ensureConfigRunning(rawConfig string, configType string) error {
expectedBytes := []byte(rawConfig)
if configType != "json" {
adapter := caddyconfig.GetAdapter(configType)
if adapter == nil {
return fmt.Errorf("adapter of config type is missing: %s", configType)
}
expectedBytes, _, _ = adapter.Adapt([]byte(rawConfig), nil)
}
var expected any
err := json.Unmarshal(expectedBytes, &expected)
if err != nil {
return err
}
func (tc *Tester) GetCurrentConfig(receiver any) error {
client := &http.Client{
Timeout: Default.LoadRequestTimeout,
}
fetchConfig := func(client *http.Client) any {
resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", Default.AdminPort))
if err != nil {
return nil
}
defer resp.Body.Close()
actualBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil
}
var actual any
err = json.Unmarshal(actualBytes, &actual)
if err != nil {
return nil
}
return actual
resp, err := client.Get(fmt.Sprintf("http://localhost:%d/config/", Default.AdminPort))
if err != nil {
return err
}
// TODO: does this really need to be tried more than once?
// Caddy should block until the new config is loaded, which means needing to wait is a caddy bug
for retries := 3; retries > 0; retries-- {
if reflect.DeepEqual(expected, fetchConfig(client)) {
return nil
}
time.Sleep(1 * time.Second)
defer resp.Body.Close()
actualBytes, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return errors.New("EnsureConfigRunning: POSTed configuration isn't active")
err = json.Unmarshal(actualBytes, receiver)
if err != nil {
return err
}
return nil
}
const initConfig = `{
@ -258,15 +228,6 @@ func isCaddyAdminRunning() error {
return nil
}
func getIntegrationDir() string {
_, filename, _, ok := runtime.Caller(1)
if !ok {
panic("unable to determine the current file path")
}
return path.Dir(filename)
}
// CreateTestingTransport creates a testing transport that forces call dialing connections to happen locally
func CreateTestingTransport() *http.Transport {
dialer := net.Dialer{

View file

@ -19,12 +19,13 @@ func AssertLoadError(t *testing.T, rawConfig string, configType string, expected
require.NoError(t, err)
err = tc.LaunchCaddy()
require.NoError(t, err)
defer tc.CleanupCaddy()
err = tc.LoadConfig(rawConfig, configType)
if !strings.Contains(err.Error(), expectedError) {
t.Errorf("expected error \"%s\" but got \"%s\"", expectedError, err.Error())
}
err = tc.CleanupCaddy()
require.NoError(t, err)
}
// CompareAdapt adapts a config and then compares it against an expected result

View file

@ -6,7 +6,9 @@ import (
"fmt"
"io"
"net/http"
"path"
"regexp"
"runtime"
"testing"
"github.com/stretchr/testify/require"
@ -21,6 +23,15 @@ func prependCaddyFilePath(rawConfig string) string {
return r
}
func getIntegrationDir() string {
_, filename, _, ok := runtime.Caller(1)
if !ok {
panic("unable to determine the current file path")
}
return path.Dir(filename)
}
var (
matchKey = regexp.MustCompile(`(/[\w\d\.]+\.key)`)
matchCert = regexp.MustCompile(`(/[\w\d\.]+\.crt)`)
@ -64,7 +75,9 @@ func (tc *TestHarness) init() {
tc.tester = tester
err = tc.tester.LaunchCaddy()
if err != nil {
tc.t.Errorf("Failed to launch caddy tester: %s", err)
tc.t.Errorf("Failed to launch caddy server: %s", err)
tc.t.FailNow()
return
}
// cleanup
tc.t.Cleanup(func() {
@ -87,6 +100,7 @@ func (tc *TestHarness) init() {
err = tc.tester.CleanupCaddy()
if err != nil {
tc.t.Errorf("failed to clean up caddy instance: %s", err)
tc.t.FailNow()
}
})
}