mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-14 06:46:27 +03:00
b8cba62643
This is a breaking change primarily in two areas: - Storage paths for certificates have changed - Slight changes to JSON config parameters Huge improvements in this commit, to be detailed more in the release notes. The upcoming PKI app will be powered by Smallstep libraries.
324 lines
6.7 KiB
Go
324 lines
6.7 KiB
Go
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package caddy
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
func TestReplacer(t *testing.T) {
|
|
type testCase struct {
|
|
input, expect, empty string
|
|
}
|
|
|
|
rep := testReplacer()
|
|
|
|
// ReplaceAll
|
|
for i, tc := range []testCase{
|
|
{
|
|
input: "{",
|
|
expect: "{",
|
|
},
|
|
{
|
|
input: "foo{",
|
|
expect: "foo{",
|
|
},
|
|
{
|
|
input: "foo{bar",
|
|
expect: "foo{bar",
|
|
},
|
|
{
|
|
input: "foo{bar}",
|
|
expect: "foo",
|
|
},
|
|
{
|
|
input: "}",
|
|
expect: "}",
|
|
},
|
|
{
|
|
input: "{}",
|
|
expect: "",
|
|
},
|
|
{
|
|
input: `{"json": "object"}`,
|
|
expect: "",
|
|
},
|
|
{
|
|
input: `{{`,
|
|
expect: "{{",
|
|
},
|
|
{
|
|
input: `{{}`,
|
|
expect: "",
|
|
},
|
|
{
|
|
input: `{unknown}`,
|
|
empty: "-",
|
|
expect: "-",
|
|
},
|
|
} {
|
|
actual := rep.ReplaceAll(tc.input, tc.empty)
|
|
if actual != tc.expect {
|
|
t.Errorf("Test %d: '%s': expected '%s' but got '%s'",
|
|
i, tc.input, tc.expect, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReplacerSet(t *testing.T) {
|
|
rep := testReplacer()
|
|
|
|
for _, tc := range []struct {
|
|
variable string
|
|
value string
|
|
}{
|
|
{
|
|
variable: "test1",
|
|
value: "val1",
|
|
},
|
|
{
|
|
variable: "asdf",
|
|
value: "123",
|
|
},
|
|
{
|
|
variable: "äöü",
|
|
value: "öö_äü",
|
|
},
|
|
{
|
|
variable: "with space",
|
|
value: "space value",
|
|
},
|
|
{
|
|
variable: "1",
|
|
value: "test-123",
|
|
},
|
|
{
|
|
variable: "mySuper_IP",
|
|
value: "1.2.3.4",
|
|
},
|
|
{
|
|
variable: "testEmpty",
|
|
value: "",
|
|
},
|
|
} {
|
|
rep.Set(tc.variable, tc.value)
|
|
|
|
// test if key is added
|
|
if val, ok := rep.static[tc.variable]; ok {
|
|
if val != tc.value {
|
|
t.Errorf("Expected value '%s' for key '%s' got '%s'", tc.value, tc.variable, val)
|
|
}
|
|
} else {
|
|
t.Errorf("Expected existing key '%s' found nothing", tc.variable)
|
|
}
|
|
}
|
|
|
|
// test if all keys are still there (by length)
|
|
length := len(rep.static)
|
|
if len(rep.static) != 7 {
|
|
t.Errorf("Expected length '%v' got '%v'", 7, length)
|
|
}
|
|
}
|
|
|
|
func TestReplacerReplaceKnown(t *testing.T) {
|
|
rep := Replacer{
|
|
providers: []ReplacerFunc{
|
|
// split our possible vars to two functions (to test if both functions are called)
|
|
func(key string) (val string, ok bool) {
|
|
switch key {
|
|
case "test1":
|
|
return "val1", true
|
|
case "asdf":
|
|
return "123", true
|
|
case "äöü":
|
|
return "öö_äü", true
|
|
case "with space":
|
|
return "space value", true
|
|
default:
|
|
return "NOOO", false
|
|
}
|
|
},
|
|
func(key string) (val string, ok bool) {
|
|
switch key {
|
|
case "1":
|
|
return "test-123", true
|
|
case "mySuper_IP":
|
|
return "1.2.3.4", true
|
|
case "testEmpty":
|
|
return "", true
|
|
default:
|
|
return "NOOO", false
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range []struct {
|
|
testInput string
|
|
expected string
|
|
}{
|
|
{
|
|
// test vars without space
|
|
testInput: "{test1}{asdf}{äöü}{1}{with space}{mySuper_IP}",
|
|
expected: "val1123öö_äütest-123space value1.2.3.4",
|
|
},
|
|
{
|
|
// test vars with space
|
|
testInput: "{test1} {asdf} {äöü} {1} {with space} {mySuper_IP} ",
|
|
expected: "val1 123 öö_äü test-123 space value 1.2.3.4 ",
|
|
},
|
|
{
|
|
// test with empty val
|
|
testInput: "{test1} {testEmpty} {asdf} {1} ",
|
|
expected: "val1 EMPTY 123 test-123 ",
|
|
},
|
|
{
|
|
// test vars with not finished placeholders
|
|
testInput: "{te{test1}{as{{df{1}",
|
|
expected: "{teval1{as{{dftest-123",
|
|
},
|
|
{
|
|
// test with non existing vars
|
|
testInput: "{test1} {nope} {1} ",
|
|
expected: "val1 {nope} test-123 ",
|
|
},
|
|
} {
|
|
actual := rep.ReplaceKnown(tc.testInput, "EMPTY")
|
|
|
|
// test if all are replaced as expected
|
|
if actual != tc.expected {
|
|
t.Errorf("Expected '%s' got '%s' for '%s'", tc.expected, actual, tc.testInput)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReplacerDelete(t *testing.T) {
|
|
rep := Replacer{
|
|
static: map[string]string{
|
|
"key1": "val1",
|
|
"key2": "val2",
|
|
"key3": "val3",
|
|
"key4": "val4",
|
|
},
|
|
}
|
|
|
|
startLen := len(rep.static)
|
|
|
|
toDel := []string{
|
|
"key2", "key4",
|
|
}
|
|
|
|
for _, key := range toDel {
|
|
rep.Delete(key)
|
|
|
|
// test if key is removed from static map
|
|
if _, ok := rep.static[key]; ok {
|
|
t.Errorf("Expected '%s' to be removed. It is still in static map.", key)
|
|
}
|
|
}
|
|
|
|
// check if static slice is smaller
|
|
expected := startLen - len(toDel)
|
|
actual := len(rep.static)
|
|
if len(rep.static) != expected {
|
|
t.Errorf("Expected length '%v' got length '%v'", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestReplacerMap(t *testing.T) {
|
|
rep := testReplacer()
|
|
|
|
for i, tc := range []ReplacerFunc{
|
|
func(key string) (val string, ok bool) {
|
|
return "", false
|
|
},
|
|
func(key string) (val string, ok bool) {
|
|
return "", false
|
|
},
|
|
} {
|
|
rep.Map(tc)
|
|
|
|
// test if function (which listens on specific key) is added by checking length
|
|
if len(rep.providers) == i+1 {
|
|
// check if the last function is the one we just added
|
|
pTc := fmt.Sprintf("%p", tc)
|
|
pRep := fmt.Sprintf("%p", rep.providers[i])
|
|
if pRep != pTc {
|
|
t.Errorf("Expected func pointer '%s' got '%s'", pTc, pRep)
|
|
}
|
|
} else {
|
|
t.Errorf("Expected providers length '%v' got length '%v'", i+1, len(rep.providers))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReplacerNew(t *testing.T) {
|
|
rep := NewReplacer()
|
|
|
|
if len(rep.providers) != 2 {
|
|
t.Errorf("Expected providers length '%v' got length '%v'", 2, len(rep.providers))
|
|
} else {
|
|
// test if default global replacements are added as the first provider
|
|
hostname, _ := os.Hostname()
|
|
os.Setenv("CADDY_REPLACER_TEST", "envtest")
|
|
defer os.Setenv("CADDY_REPLACER_TEST", "")
|
|
|
|
for _, tc := range []struct {
|
|
variable string
|
|
value string
|
|
}{
|
|
{
|
|
variable: "system.hostname",
|
|
value: hostname,
|
|
},
|
|
{
|
|
variable: "system.slash",
|
|
value: string(filepath.Separator),
|
|
},
|
|
{
|
|
variable: "system.os",
|
|
value: runtime.GOOS,
|
|
},
|
|
{
|
|
variable: "system.arch",
|
|
value: runtime.GOARCH,
|
|
},
|
|
{
|
|
variable: "env.CADDY_REPLACER_TEST",
|
|
value: "envtest",
|
|
},
|
|
} {
|
|
if val, ok := rep.providers[0](tc.variable); ok {
|
|
if val != tc.value {
|
|
t.Errorf("Expected value '%s' for key '%s' got '%s'", tc.value, tc.variable, val)
|
|
}
|
|
} else {
|
|
t.Errorf("Expected key '%s' to be recognized by first provider", tc.variable)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func testReplacer() Replacer {
|
|
return Replacer{
|
|
providers: make([]ReplacerFunc, 0),
|
|
static: make(map[string]string),
|
|
}
|
|
}
|