Files
uncloud/internal/machine/caddyconfig/caddyfile_test.go
T

191 lines
4.3 KiB
Go

package caddyconfig
import (
"context"
"testing"
"github.com/psviderski/uncloud/internal/machine/store"
"github.com/psviderski/uncloud/pkg/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCaddyfileGenerator(t *testing.T) {
caddyfileHeader := `http:// {
handle /.uncloud-verify {
respond "test-machine-id" 200
}
log
}
(common_proxy) {
# Retry failed requests up to lb_retries times against other available upstreams.
lb_retries 3
# Upstreams are marked unhealthy for fail_duration after a failed request (passive health checking).
fail_duration 30s
}
`
// TODO: mock validator
generator := NewCaddyfileGenerator("test-machine-id", nil, nil)
tests := []struct {
name string
containers []store.ContainerRecord
want string
wantErr bool
}{
{
name: "empty containers",
containers: []store.ContainerRecord{},
want: caddyfileHeader,
},
{
name: "HTTP container",
containers: []store.ContainerRecord{
newContainerRecord(newContainer("10.210.0.2", "app.example.com:8080/http"), "mach1"),
},
want: caddyfileHeader + `
http://app.example.com {
reverse_proxy {
to 10.210.0.2:8080
import common_proxy
}
log
}
`,
},
{
name: "load balancing multiple containers",
containers: []store.ContainerRecord{
newContainerRecord(newContainer("10.210.0.2", "app.example.com:8080/http"), "mach1"),
newContainerRecord(newContainer("10.210.0.3", "app.example.com:8080/http"), "mach1"),
},
want: caddyfileHeader + `
http://app.example.com {
reverse_proxy {
to 10.210.0.2:8080 10.210.0.3:8080
import common_proxy
}
log
}
`,
},
{
name: "HTTPS container",
containers: []store.ContainerRecord{
newContainerRecord(newContainer("10.210.0.2", "secure.example.com:8000/https"), "mach1"),
},
want: caddyfileHeader + `
https://secure.example.com {
reverse_proxy {
to 10.210.0.2:8000
import common_proxy
}
log
}
`,
},
{
name: "mixed HTTP and HTTPS",
containers: []store.ContainerRecord{
newContainerRecord(
newContainer("10.210.0.2",
"app.example.com:8080/http",
"web.example.com:8000/http"),
"mach1",
),
newContainerRecord(
newContainer("10.210.0.3",
"app.example.com:8080/http",
"secure.example.com:8888/https"),
"mach1",
),
newContainerRecord(
newContainer("10.210.0.4",
"web.example.com:8000/http",
"secure.example.com:8888/https"),
"mach1",
),
newContainerRecord(
newContainer("10.210.0.5",
"app.example.com:8080/http",
"web.example.com:8000/http",
"secure.example.com:8888/https"),
"mach1",
),
},
want: caddyfileHeader + `
http://app.example.com {
reverse_proxy {
to 10.210.0.2:8080 10.210.0.3:8080 10.210.0.5:8080
import common_proxy
}
log
}
http://web.example.com {
reverse_proxy {
to 10.210.0.2:8000 10.210.0.4:8000 10.210.0.5:8000
import common_proxy
}
log
}
https://secure.example.com {
reverse_proxy {
to 10.210.0.3:8888 10.210.0.4:8888 10.210.0.5:8888
import common_proxy
}
log
}
`,
},
{
name: "container without uncloud network ignored",
containers: []store.ContainerRecord{
newContainerRecord(newContainerWithoutNetwork("ignored.example.com:8080/http"), "mach1"),
},
want: caddyfileHeader,
},
{
name: "container with invalid port ignored",
containers: []store.ContainerRecord{
newContainerRecord(newContainer("10.210.0.2", "invalid-port"), "mach1"),
},
want: caddyfileHeader,
},
{
name: "containers with unsupported protocols and host mode ignored",
containers: []store.ContainerRecord{
newContainerRecord(newContainer("10.210.0.2", "5000/tcp"), "mach1"),
newContainerRecord(newContainer("10.210.0.3", "5000/udp"), "mach1"),
newContainerRecord(newContainer("10.210.0.4", "80:8080/tcp@host"), "mach1"),
},
want: caddyfileHeader,
},
}
ctx := context.Background()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config, err := generator.Generate(ctx, tt.containers)
if tt.wantErr {
assert.Error(t, err)
return
}
require.NoError(t, err)
assert.Equal(t, tt.want, config, "Generated Caddyfile doesn't match")
})
}
}
func newContainerRecord(ctr api.ServiceContainer, machineID string) store.ContainerRecord {
return store.ContainerRecord{
Container: ctr,
MachineID: machineID,
}
}