mirror of
https://github.com/psviderski/uncloud.git
synced 2026-11-10 12:44:16 +00:00
264 lines
8.9 KiB
Go
264 lines
8.9 KiB
Go
package caddy
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/psviderski/uncloud/pkg/api"
|
|
"github.com/psviderski/uncloud/pkg/client"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestResolveDeploymentOptions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const (
|
|
customImage = "example.com/caddy:1.2.3"
|
|
customConfig = "{\n\tdebug\n}"
|
|
)
|
|
machines := api.Placement{Machines: []string{"m1", "m2"}}
|
|
|
|
// A service with a custom image, config, and machines that has the given labels.
|
|
service := func(labels ...string) api.ServiceSpec {
|
|
spec := api.ServiceSpec{
|
|
Name: client.CaddyServiceName,
|
|
Caddy: &api.CaddySpec{Config: customConfig},
|
|
Container: api.ContainerSpec{Image: customImage},
|
|
Placement: machines,
|
|
}
|
|
if len(labels) > 0 {
|
|
spec.Labels = make(map[string]string, len(labels))
|
|
for _, label := range labels {
|
|
spec.Labels[label] = ""
|
|
}
|
|
}
|
|
return spec
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
current api.ServiceSpec
|
|
opts deployOptions
|
|
config string
|
|
want client.CaddyDeploymentOptions
|
|
}{
|
|
{
|
|
name: "no service gets the defaults",
|
|
},
|
|
{
|
|
name: "service that isn't managed gets the defaults",
|
|
current: service(),
|
|
},
|
|
{
|
|
name: "managed service follows the default image and config and keeps machines",
|
|
current: service(api.LabelCaddyManaged),
|
|
want: client.CaddyDeploymentOptions{Placement: machines},
|
|
},
|
|
{
|
|
name: "custom image is kept and config follows the default",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyImageCustom),
|
|
want: client.CaddyDeploymentOptions{Image: customImage, Placement: machines},
|
|
},
|
|
{
|
|
name: "custom config is kept and image follows the latest version",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyConfigCustom),
|
|
want: client.CaddyDeploymentOptions{Config: new(customConfig), Placement: machines},
|
|
},
|
|
{
|
|
name: "custom image and config are kept",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyImageCustom, api.LabelCaddyConfigCustom),
|
|
want: client.CaddyDeploymentOptions{Image: customImage, Config: new(customConfig), Placement: machines},
|
|
},
|
|
{
|
|
name: "custom empty config is kept",
|
|
current: api.ServiceSpec{
|
|
Name: client.CaddyServiceName,
|
|
Labels: map[string]string{api.LabelCaddyManaged: "", api.LabelCaddyConfigCustom: ""},
|
|
},
|
|
want: client.CaddyDeploymentOptions{Config: new("")},
|
|
},
|
|
{
|
|
name: "image flag overrides the current image",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyImageCustom),
|
|
opts: deployOptions{image: "caddy:2", imageChanged: true},
|
|
want: client.CaddyDeploymentOptions{Image: "caddy:2", Placement: machines},
|
|
},
|
|
{
|
|
name: "empty image flag resets to the latest version",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyImageCustom),
|
|
opts: deployOptions{imageChanged: true},
|
|
want: client.CaddyDeploymentOptions{Placement: machines},
|
|
},
|
|
{
|
|
name: "caddyfile flag overrides the current config",
|
|
current: service(api.LabelCaddyManaged),
|
|
opts: deployOptions{caddyfile: "global.Caddyfile", caddyfileChanged: true},
|
|
config: "{\n\tstorage redis\n}",
|
|
want: client.CaddyDeploymentOptions{Config: new("{\n\tstorage redis\n}"), Placement: machines},
|
|
},
|
|
{
|
|
name: "caddyfile flag with an empty file sets a custom empty config",
|
|
current: service(api.LabelCaddyManaged),
|
|
opts: deployOptions{caddyfile: "empty.Caddyfile", caddyfileChanged: true},
|
|
want: client.CaddyDeploymentOptions{Config: new(""), Placement: machines},
|
|
},
|
|
{
|
|
name: "empty caddyfile flag resets to the default config",
|
|
current: service(api.LabelCaddyManaged, api.LabelCaddyConfigCustom),
|
|
opts: deployOptions{caddyfileChanged: true},
|
|
want: client.CaddyDeploymentOptions{Placement: machines},
|
|
},
|
|
{
|
|
name: "machine flag overrides the current machines",
|
|
current: service(api.LabelCaddyManaged),
|
|
opts: deployOptions{machines: []string{"m3,m4", "m5"}, machinesChanged: true},
|
|
want: client.CaddyDeploymentOptions{Placement: api.Placement{Machines: []string{"m3", "m4", "m5"}}},
|
|
},
|
|
{
|
|
name: "empty machine flag resets to all machines",
|
|
current: service(api.LabelCaddyManaged),
|
|
opts: deployOptions{machines: []string{}, machinesChanged: true},
|
|
},
|
|
{
|
|
name: "flags apply to a service that isn't managed",
|
|
current: service(),
|
|
opts: deployOptions{
|
|
image: "caddy:2", imageChanged: true,
|
|
caddyfile: "global.Caddyfile", caddyfileChanged: true,
|
|
machines: []string{"m3"}, machinesChanged: true,
|
|
},
|
|
config: customConfig,
|
|
want: client.CaddyDeploymentOptions{
|
|
Image: "caddy:2",
|
|
Config: new(customConfig),
|
|
Placement: api.Placement{Machines: []string{"m3"}},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.want, resolveDeploymentOptions(tt.current, tt.opts, tt.config))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeploymentWarnings(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const (
|
|
defaultImage = client.CaddyImage + ":0.1.3"
|
|
customImage = "example.com/caddy:1.2.3"
|
|
localConfig = "{\n\tdebug\n}"
|
|
override = "doesn't manage this caddy service yet"
|
|
storage = "certificate storage changes from"
|
|
keepStorage = "To keep the current storage"
|
|
module = "must include the Uncloud storage module"
|
|
)
|
|
managed := map[string]string{api.LabelCaddyManaged: ""}
|
|
|
|
service := func(image, config string, labels map[string]string) api.ServiceSpec {
|
|
spec := api.ServiceSpec{
|
|
Name: client.CaddyServiceName,
|
|
Container: api.ContainerSpec{Image: image},
|
|
Labels: labels,
|
|
}
|
|
if config != "" {
|
|
spec.Caddy = &api.CaddySpec{Config: config}
|
|
}
|
|
return spec
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
current api.ServiceSpec
|
|
target api.ServiceSpec
|
|
opts deployOptions
|
|
want []string
|
|
notWant []string
|
|
}{
|
|
{
|
|
name: "new service with defaults has no warnings",
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
notWant: []string{override, storage, module},
|
|
},
|
|
{
|
|
name: "new service with a custom image",
|
|
target: service(customImage, client.DefaultCaddyConfig, managed),
|
|
want: []string{module},
|
|
notWant: []string{override, storage},
|
|
},
|
|
{
|
|
name: "service that isn't managed moves to cluster storage",
|
|
current: service("caddy:2.11.4", "", nil),
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
want: []string{override, "from local to cluster", keepStorage},
|
|
notWant: []string{module},
|
|
},
|
|
{
|
|
name: "service that isn't managed already uses cluster storage",
|
|
current: service(defaultImage, client.DefaultCaddyConfig, nil),
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
want: []string{override},
|
|
notWant: []string{storage, module},
|
|
},
|
|
{
|
|
name: "managed service without changes has no warnings",
|
|
current: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
notWant: []string{override, storage, module},
|
|
},
|
|
{
|
|
name: "managed service upgrades the default image",
|
|
current: service(client.CaddyImage+":0.1.2", client.DefaultCaddyConfig, managed),
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
notWant: []string{override, storage, module},
|
|
},
|
|
{
|
|
name: "custom caddyfile moves to local storage",
|
|
current: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
target: service(defaultImage, localConfig, managed),
|
|
opts: deployOptions{caddyfile: "global.Caddyfile", caddyfileChanged: true},
|
|
want: []string{"from cluster to local"},
|
|
notWant: []string{override, keepStorage, module},
|
|
},
|
|
{
|
|
name: "other storage module is named",
|
|
current: service(defaultImage, "{\n\tstorage redis\n}", managed),
|
|
target: service(defaultImage, client.DefaultCaddyConfig, managed),
|
|
want: []string{"from 'redis' to cluster", keepStorage},
|
|
},
|
|
{
|
|
name: "custom image is unchanged with the same config",
|
|
current: service(customImage, client.DefaultCaddyConfig, managed),
|
|
target: service(customImage, client.DefaultCaddyConfig, managed),
|
|
notWant: []string{override, storage, module},
|
|
},
|
|
{
|
|
name: "custom image receives a changed default config",
|
|
current: service(customImage, "{\n\tstorage uncloud\n\tdebug\n}", managed),
|
|
target: service(customImage, client.DefaultCaddyConfig, managed),
|
|
want: []string{module},
|
|
notWant: []string{override, storage},
|
|
},
|
|
{
|
|
name: "custom image with local storage",
|
|
current: service(defaultImage, localConfig, managed),
|
|
target: service(customImage, localConfig, managed),
|
|
notWant: []string{override, storage, module},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
warnings := strings.Join(deploymentWarnings(tt.current, tt.target, tt.opts), "\n")
|
|
for _, want := range tt.want {
|
|
assert.Contains(t, warnings, want)
|
|
}
|
|
for _, notWant := range tt.notWant {
|
|
assert.NotContains(t, warnings, notWant)
|
|
}
|
|
})
|
|
}
|
|
}
|