some tests?
This commit is contained in:
296
main_test.go
Normal file
296
main_test.go
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseEnvLine(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
line string
|
||||||
|
wantKey string
|
||||||
|
wantValue string
|
||||||
|
wantOK bool
|
||||||
|
}{
|
||||||
|
{name: "simple", line: "FOO=bar", wantKey: "FOO", wantValue: "bar", wantOK: true},
|
||||||
|
{name: "trims", line: " FOO = bar ", wantKey: "FOO", wantValue: "bar", wantOK: true},
|
||||||
|
{name: "comment", line: "# comment", wantOK: false},
|
||||||
|
{name: "empty", line: "", wantOK: false},
|
||||||
|
{name: "no equals", line: "FOO", wantOK: false},
|
||||||
|
{name: "invalid key digit", line: "1FOO=bar", wantOK: false},
|
||||||
|
{name: "invalid key dash", line: "FOO-BAR=1", wantOK: false},
|
||||||
|
{name: "underscore ok", line: "_FOO=bar", wantKey: "_FOO", wantValue: "bar", wantOK: true},
|
||||||
|
{name: "digit ok after", line: "FOO1=2", wantKey: "FOO1", wantValue: "2", wantOK: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
key, value, ok := parseEnvLine(tt.line)
|
||||||
|
if ok != tt.wantOK {
|
||||||
|
t.Fatalf("ok=%v want %v", ok, tt.wantOK)
|
||||||
|
}
|
||||||
|
if key != tt.wantKey || value != tt.wantValue {
|
||||||
|
t.Fatalf("got key=%q value=%q want key=%q value=%q", key, value, tt.wantKey, tt.wantValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsEnvKey(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
key string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{key: "A", want: true},
|
||||||
|
{key: "_A", want: true},
|
||||||
|
{key: "A1", want: true},
|
||||||
|
{key: "A_B2", want: true},
|
||||||
|
{key: "", want: false},
|
||||||
|
{key: "1A", want: false},
|
||||||
|
{key: "A-B", want: false},
|
||||||
|
{key: "A B", want: false},
|
||||||
|
{key: "A.B", want: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.key, func(t *testing.T) {
|
||||||
|
if got := isEnvKey(tt.key); got != tt.want {
|
||||||
|
t.Fatalf("got %v want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsEnvLine(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
line string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{line: "", want: true},
|
||||||
|
{line: " ", want: true},
|
||||||
|
{line: "FOO=bar", want: true},
|
||||||
|
{line: "FOO = bar", want: false},
|
||||||
|
{line: "1FOO=bar", want: false},
|
||||||
|
{line: "NO_EQUALS", want: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.line, func(t *testing.T) {
|
||||||
|
if got := isEnvLine(tt.line); got != tt.want {
|
||||||
|
t.Fatalf("got %v want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApplyEnvAssignments(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
lines := []string{
|
||||||
|
"# comment",
|
||||||
|
"FOO=old",
|
||||||
|
"BAR=keep",
|
||||||
|
"INVALID LINE",
|
||||||
|
"BAZ=gone",
|
||||||
|
"FOO=duplicate",
|
||||||
|
}
|
||||||
|
assignments := []envAssignment{
|
||||||
|
{key: "FOO", value: "new"},
|
||||||
|
{key: "BAZ", value: "zzz"},
|
||||||
|
{key: "NEWKEY", value: "123"},
|
||||||
|
}
|
||||||
|
want := []string{
|
||||||
|
"# comment",
|
||||||
|
"FOO=new",
|
||||||
|
"BAR=keep",
|
||||||
|
"INVALID LINE",
|
||||||
|
"BAZ=zzz",
|
||||||
|
"NEWKEY=123",
|
||||||
|
}
|
||||||
|
|
||||||
|
got := applyEnvAssignments(lines, assignments)
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("got %#v want %#v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveEnvKeys(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
lines := []string{
|
||||||
|
"KEEP=1",
|
||||||
|
"DROP=2",
|
||||||
|
"# comment",
|
||||||
|
"INVALID LINE",
|
||||||
|
"DROP=3",
|
||||||
|
"ALSO=4",
|
||||||
|
}
|
||||||
|
keys := []string{"DROP", "MISSING"}
|
||||||
|
want := []string{
|
||||||
|
"KEEP=1",
|
||||||
|
"# comment",
|
||||||
|
"INVALID LINE",
|
||||||
|
"ALSO=4",
|
||||||
|
}
|
||||||
|
|
||||||
|
got := removeEnvKeys(lines, keys)
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("got %#v want %#v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShellQuote(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{name: "empty", input: "", want: "''"},
|
||||||
|
{name: "simple", input: "abc", want: "'abc'"},
|
||||||
|
{name: "spaces", input: "a b", want: "'a b'"},
|
||||||
|
{name: "single quote", input: "a'b", want: "'a'\"'\"'b'"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := shellQuote(tt.input); got != tt.want {
|
||||||
|
t.Fatalf("got %q want %q", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveVolumePath(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
template string
|
||||||
|
baseDir string
|
||||||
|
service string
|
||||||
|
wantResult string
|
||||||
|
}{
|
||||||
|
{name: "empty uses base", template: "", baseDir: "/srv/pb", service: "svc", wantResult: "/srv/pb"},
|
||||||
|
{name: "absolute path", template: "/data/{service}", baseDir: "/srv/pb", service: "svc", wantResult: "/data/svc"},
|
||||||
|
{name: "relative path", template: "data/{service}", baseDir: "/srv/pb", service: "svc", wantResult: "/srv/pb/data/svc"},
|
||||||
|
{name: "simple relative", template: "custom", baseDir: "/srv/pb", service: "svc", wantResult: "/srv/pb/custom"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := resolveVolumePath(tt.template, tt.baseDir, tt.service); got != tt.wantResult {
|
||||||
|
t.Fatalf("got %q want %q", got, tt.wantResult)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTranslateMachineArch(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{name: "x86_64", input: " x86_64 ", want: "amd64"},
|
||||||
|
{name: "amd64", input: "amd64", want: "amd64"},
|
||||||
|
{name: "i686", input: "i686", want: "386"},
|
||||||
|
{name: "armv7l", input: "armv7l", want: "armv7"},
|
||||||
|
{name: "armv6l", input: "armv6l", want: "arm"},
|
||||||
|
{name: "aarch64", input: "aarch64", want: "arm64"},
|
||||||
|
{name: "arm64", input: "arm64", want: "arm64"},
|
||||||
|
{name: "unknown", input: "mips", wantErr: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := translateMachineArch(tt.input)
|
||||||
|
if tt.wantErr {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Fatalf("got %q want %q", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSystemdScript(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
serviceDir := "/srv/pb"
|
||||||
|
envFile := "/etc/pb/env"
|
||||||
|
serviceName := "demo"
|
||||||
|
script := systemdScript(serviceDir, envFile, serviceName)
|
||||||
|
|
||||||
|
required := []string{
|
||||||
|
"/etc/systemd/system/pb@.service",
|
||||||
|
"StandardOutput = append:" + serviceDir + "/%i.log",
|
||||||
|
"StandardError = append:" + serviceDir + "/%i.log",
|
||||||
|
"WorkingDirectory = " + serviceDir,
|
||||||
|
"EnvironmentFile = " + envFile,
|
||||||
|
"ExecStart = " + serviceDir + "/pocketbase serve --http=127.0.0.1:${PORT} --hooksWatch=false --dir=${DATA_DIR} --hooksDir=" + serviceDir + "/pb_hooks --migrationsDir=" + serviceDir + "/pb_migrations --publicDir=" + serviceDir + "/pb_public",
|
||||||
|
"systemctl --no-block enable pb@" + serviceName,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, snippet := range required {
|
||||||
|
if !strings.Contains(script, snippet) {
|
||||||
|
t.Fatalf("script missing %q", snippet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSystemdOverrideScript(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
serviceName := "demo"
|
||||||
|
port := 8090
|
||||||
|
volume := "/srv/pb/data"
|
||||||
|
script := systemdOverrideScript(serviceName, port, volume)
|
||||||
|
|
||||||
|
required := []string{
|
||||||
|
"/etc/systemd/system/pb@" + serviceName + ".service.d",
|
||||||
|
"Environment=PORT=8090",
|
||||||
|
"Environment=DATA_DIR=" + volume,
|
||||||
|
}
|
||||||
|
for _, snippet := range required {
|
||||||
|
if !strings.Contains(script, snippet) {
|
||||||
|
t.Fatalf("script missing %q", snippet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSystemdRestartScript(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
serviceName := "demo"
|
||||||
|
script := systemdRestartScript(serviceName)
|
||||||
|
expected := "systemctl --no-block restart pb@" + serviceName
|
||||||
|
if !strings.Contains(script, expected) {
|
||||||
|
t.Fatalf("script missing %q", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user