mirror of
https://github.com/Pacerino/CaddyProxyManager.git
synced 2026-08-04 03:05:30 -04:00
Older Caddy versions don't support `list-modules --json`, which made the plugins page fail with an opaque "exit status 1". Surface stderr in the error and fall back to parsing the plain-text output (--packages / --skip-standard) when --json is unsupported, so module detection works on any Caddy version.
118 lines
3.3 KiB
Go
118 lines
3.3 KiB
Go
package caddy
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/Pacerino/CaddyProxyManager/internal/config"
|
|
)
|
|
|
|
// TestListModules points the configured Caddy binary at a fake script that
|
|
// emits a known list-modules JSON payload, exercising the exec + parse path.
|
|
func TestListModules(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("fake shell binary not supported on windows")
|
|
}
|
|
prev := config.Configuration.Caddy.Binary
|
|
t.Cleanup(func() { config.Configuration.Caddy.Binary = prev })
|
|
|
|
script := filepath.Join(t.TempDir(), "fakecaddy")
|
|
body := `#!/bin/sh
|
|
cat <<'EOF'
|
|
[
|
|
{"module_name":"http.handlers.reverse_proxy","module_type":"standard","version":"v2","package_url":"caddy"},
|
|
{"module_name":"dns.providers.cloudflare","module_type":"non-standard","version":"","package_url":"caddy-dns/cloudflare"}
|
|
]
|
|
EOF
|
|
`
|
|
if err := os.WriteFile(script, []byte(body), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
config.Configuration.Caddy.Binary = script
|
|
|
|
mods, err := ListModules()
|
|
if err != nil {
|
|
t.Fatalf("ListModules: %v", err)
|
|
}
|
|
if len(mods) != 2 {
|
|
t.Fatalf("expected 2 modules, got %d", len(mods))
|
|
}
|
|
// Sorted: dns.providers.cloudflare first.
|
|
if mods[0].ID != "dns.providers.cloudflare" || mods[0].Standard {
|
|
t.Errorf("unexpected first module: %+v", mods[0])
|
|
}
|
|
}
|
|
|
|
// TestListModulesTextFallback simulates an older Caddy that rejects --json but
|
|
// supports the plain-text flags, exercising the text-parsing fallback.
|
|
func TestListModulesTextFallback(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("fake shell binary not supported on windows")
|
|
}
|
|
prev := config.Configuration.Caddy.Binary
|
|
t.Cleanup(func() { config.Configuration.Caddy.Binary = prev })
|
|
|
|
script := filepath.Join(t.TempDir(), "fakecaddy")
|
|
body := `#!/bin/sh
|
|
# Reject --json like older caddy does.
|
|
for a in "$@"; do
|
|
if [ "$a" = "--json" ]; then
|
|
echo "Error: unknown flag: --json" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
# --skip-standard returns only the plugin(s).
|
|
case "$*" in
|
|
*--skip-standard*)
|
|
echo "dns.providers.cloudflare github.com/caddy-dns/cloudflare"
|
|
;;
|
|
*)
|
|
echo "http.handlers.reverse_proxy github.com/caddyserver/caddy/v2"
|
|
echo "dns.providers.cloudflare github.com/caddy-dns/cloudflare"
|
|
echo ""
|
|
echo " Standard modules: 1"
|
|
;;
|
|
esac
|
|
`
|
|
if err := os.WriteFile(script, []byte(body), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
config.Configuration.Caddy.Binary = script
|
|
|
|
mods, err := ListModules()
|
|
if err != nil {
|
|
t.Fatalf("ListModules text fallback: %v", err)
|
|
}
|
|
if len(mods) != 2 {
|
|
t.Fatalf("expected 2 modules, got %d: %+v", len(mods), mods)
|
|
}
|
|
|
|
byID := map[string]Module{}
|
|
for _, m := range mods {
|
|
byID[m.ID] = m
|
|
}
|
|
cf, ok := byID["dns.providers.cloudflare"]
|
|
if !ok || cf.Standard {
|
|
t.Errorf("cloudflare should be present and non-standard: %+v", cf)
|
|
}
|
|
if cf.Package != "github.com/caddy-dns/cloudflare" {
|
|
t.Errorf("cloudflare package = %q", cf.Package)
|
|
}
|
|
rp, ok := byID["http.handlers.reverse_proxy"]
|
|
if !ok || !rp.Standard {
|
|
t.Errorf("reverse_proxy should be present and standard: %+v", rp)
|
|
}
|
|
}
|
|
|
|
func TestListModulesBinaryMissing(t *testing.T) {
|
|
prev := config.Configuration.Caddy.Binary
|
|
t.Cleanup(func() { config.Configuration.Caddy.Binary = prev })
|
|
|
|
config.Configuration.Caddy.Binary = "/nonexistent/definitely/not/caddy"
|
|
if _, err := ListModules(); err == nil {
|
|
t.Error("expected error when binary is missing")
|
|
}
|
|
}
|