aboutsummaryrefslogtreecommitdiffhomepage
path: root/caddytest/caddytest_assert.go
blob: 359538ad314a4a18424a8c0cb50ab1dcf57dc889 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package caddytest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"testing"

	"github.com/aryann/difflib"
	"github.com/caddyserver/caddy/v2/caddyconfig"
	"github.com/stretchr/testify/require"
)

// AssertLoadError will load a config and expect an error
func AssertLoadError(t *testing.T, rawConfig string, configType string, expectedError string) {
	tc, err := NewTester()
	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())
	}
}

// CompareAdapt adapts a config and then compares it against an expected result
func CompareAdapt(t testing.TB, filename, rawConfig string, adapterName string, expectedResponse string) bool {
	cfgAdapter := caddyconfig.GetAdapter(adapterName)
	if cfgAdapter == nil {
		t.Logf("unrecognized config adapter '%s'", adapterName)
		return false
	}

	options := make(map[string]any)

	result, warnings, err := cfgAdapter.Adapt([]byte(rawConfig), options)
	if err != nil {
		t.Logf("adapting config using %s adapter: %v", adapterName, err)
		return false
	}

	// prettify results to keep tests human-manageable
	var prettyBuf bytes.Buffer
	err = json.Indent(&prettyBuf, result, "", "\t")
	if err != nil {
		return false
	}
	result = prettyBuf.Bytes()

	if len(warnings) > 0 {
		for _, w := range warnings {
			t.Logf("warning: %s:%d: %s: %s", filename, w.Line, w.Directive, w.Message)
		}
	}

	diff := difflib.Diff(
		strings.Split(expectedResponse, "\n"),
		strings.Split(string(result), "\n"))

	// scan for failure
	failed := false
	for _, d := range diff {
		if d.Delta != difflib.Common {
			failed = true
			break
		}
	}

	if failed {
		for _, d := range diff {
			switch d.Delta {
			case difflib.Common:
				fmt.Printf("  %s\n", d.Payload)
			case difflib.LeftOnly:
				fmt.Printf(" - %s\n", d.Payload)
			case difflib.RightOnly:
				fmt.Printf(" + %s\n", d.Payload)
			}
		}
		return false
	}
	return true
}

// AssertAdapt adapts a config and then tests it against an expected result
func AssertAdapt(t testing.TB, rawConfig string, adapterName string, expectedResponse string) {
	ok := CompareAdapt(t, "Caddyfile", rawConfig, adapterName, expectedResponse)
	if !ok {
		t.Fail()
	}
}

// Generic request functions

func applyHeaders(t testing.TB, req *http.Request, requestHeaders []string) {
	requestContentType := ""
	for _, requestHeader := range requestHeaders {
		arr := strings.SplitAfterN(requestHeader, ":", 2)
		k := strings.TrimRight(arr[0], ":")
		v := strings.TrimSpace(arr[1])
		if k == "Content-Type" {
			requestContentType = v
		}
		t.Logf("Request header: %s => %s", k, v)
		req.Header.Set(k, v)
	}

	if requestContentType == "" {
		t.Logf("Content-Type header not provided")
	}
}