Files
tia-love/internal/stack/converter_test.go
T

238 lines
5.8 KiB
Go

package stack
import (
"strings"
"testing"
)
// full — output lengkap seperti tampil ke user (sudah termasuk komentar warning).
func full(r ConvertResult) string { return r.Output }
func checkGolden(t *testing.T, name, cmd, want string) {
t.Helper()
got, err := Convert(cmd)
if err != nil {
t.Fatalf("%s: Convert error: %v", name, err)
}
g := full(got)
if strings.TrimSpace(g) != strings.TrimSpace(want) {
t.Fatalf("%s: YAML beda.\n--- dapat ---\n%s\n--- mau ---\n%s", name, g, want)
}
}
func TestConvertVectors(t *testing.T) {
checkGolden(t, "V1 basic", "docker run -p 80:80 foobar/baz:latest", `
services:
baz:
ports:
- 80:80
image: foobar/baz:latest`)
checkGolden(t, "V2 flags umum",
"docker run -d --name web -p 8080:80 -v ./html:/usr/share/nginx/html:ro -e TZ=Asia/Jakarta --restart unless-stopped nginx:latest", `
services:
nginx:
container_name: web
ports:
- 8080:80
volumes:
- ./html:/usr/share/nginx/html:ro
environment:
- TZ=Asia/Jakarta
restart: unless-stopped
image: nginx:latest`)
checkGolden(t, "V3 multiline + $()", `docker run \
-d \
--name tor-relay \
-e TZ=Europe/London \
-e PUID=$(id -u) \
-v $(pwd)/tor/data:/data:Z \
-p 9001:9001 \
--restart always \
ilshidur/tor-relay`, `
services:
tor-relay:
container_name: tor-relay
environment:
- TZ=Europe/London
- PUID=$(id -u)
volumes:
- $(pwd)/tor/data:/data:Z
ports:
- 9001:9001
restart: always
image: ilshidur/tor-relay`)
checkGolden(t, "V4 kutip nilai", `docker run --name="foobar" -e GREETING="hello world" nginx`, `
services:
nginx:
container_name: foobar
environment:
- GREETING=hello world
image: nginx`)
checkGolden(t, "V5 -p nempel", "docker run -p8080:80 nginx", `
services:
nginx:
ports:
- 8080:80
image: nginx`)
checkGolden(t, "V6 flag tak dikenal", "docker run -d -z machin --unknown-long=truc nginx", `
# ignored options for 'nginx'
# -z=machin
# --unknown-long=truc
services:
nginx:
image: nginx`)
checkGolden(t, "V7 network bernama", "docker run --network appnet nginx", `
# named network 'appnet' is marked as "external" (used by service 'nginx'), so either remove "external" from network definition or it needs to be created using: docker network create -d bridge appnet
services:
nginx:
networks:
- appnet
image: nginx
networks:
appnet:
external: true
name: appnet`)
checkGolden(t, "V8 network host", "docker run --network host -p 8080:80 nginx", `
services:
nginx:
network_mode: host
image: nginx`)
checkGolden(t, "V9 named volume", "docker run -v vol:/data nginx", `
services:
nginx:
volumes:
- vol:/data
image: nginx
volumes:
vol: {}`)
checkGolden(t, "V10 mount long syntax",
"docker run --mount type=bind,source=/host,target=/container,readonly nginx", `
services:
nginx:
volumes:
- type: bind
source: /host
target: /container
readonly: true
image: nginx`)
checkGolden(t, "V11 healthcheck",
`docker run --health-cmd "curl -f http://localhost/" --health-interval 30s --health-retries 3 --health-timeout 5s --health-start-period 10s nginx`, `
services:
nginx:
healthcheck:
test: curl -f http://localhost/
interval: 30s
retries: 3
timeout: 5s
start_period: 10s
image: nginx`)
checkGolden(t, "V12 log opt", "docker run --log-opt max-size=1g --log-opt max-file=3 --restart always nginx", `
services:
nginx:
logging:
options:
max-size: 1g
max-file: 3
restart: always
image: nginx`)
checkGolden(t, "V13 limits", "docker run --memory 512m --cpus 1.5 --pids-limit 200 nginx", `
services:
nginx:
deploy:
resources:
limits:
memory: 512m
cpus: 1.5
pids: 200
image: nginx`)
checkGolden(t, "V14 gpus", "docker run --gpus all nvidia/cuda:12.0-base", `
services:
cuda:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu
image: nvidia/cuda:12.0-base`)
checkGolden(t, "V15 command setelah image", "docker run nginx:alpine nginx -g daemon off;", `
services:
nginx:
image: nginx:alpine
command: nginx -g daemon off`)
// V16 (multi perintah) menyusul — dicatat di docs/rea/composerize.md.
checkGolden(t, "V18 env-file + env", "docker run --env-file .env -e DEBUG=1 app/api:1.2", `
services:
api:
env_file:
- .env
environment:
- DEBUG=1
image: app/api:1.2`)
checkGolden(t, "V19 ulimit", "docker run --ulimit nofile=1024:2048 --ulimit nproc=65535 nginx", `
services:
nginx:
ulimits:
nofile:
soft: 1024
hard: 2048
nproc: 65535
image: nginx`)
checkGolden(t, "V20 ip + network", "docker run --network appnet --ip 10.0.0.5 nginx", `
# named network 'appnet' is marked as "external" (used by service 'nginx'), so either remove "external" from network definition or it needs to be created using: docker network create -d bridge appnet
services:
nginx:
networks:
appnet:
ipv4_address: 10.0.0.5
image: nginx
networks:
appnet:
external: true
name: appnet`)
}
func TestConvertErrors(t *testing.T) {
if _, err := Convert("foo bar"); err == nil {
t.Fatal("bukan docker run harus error")
}
if _, err := Convert("docker run -d"); err == nil {
t.Fatal("tanpa image harus error")
}
}
func TestServiceNameFromImage(t *testing.T) {
cases := map[string]string{
"nginx": "nginx",
"nginx:latest": "nginx",
"foobar/baz:latest": "baz",
"registry.local:5000/app:v1": "app",
"ghcr.io/org/app": "app",
}
for in, want := range cases {
if got := serviceNameFromImage(in); got != want {
t.Errorf("%s → %s, mau %s", in, got, want)
}
}
}