Files
zero-scale-platform/internal/platform/sql_test.go
claude 49f4a11bcc Add doctor and init; provision databases from the platform ConfigMap
- internal/platform: detect and grade storage classes (Longhorn, Ceph, Mayastor,
  LINSTOR, Portworx, GKE/Azure/AWS, NFS, local), Postgres operators (CNPG,
  Zalando, Crunchy, Percona, StackGres), MySQL operators (InnoDB Cluster, PXC,
  MariaDB, legacy shared-mysql), ingress classes, gateways and Redis
- Choose picks HA candidates (default class wins, ambiguity is an error with
  the flag to resolve it) and stores them as flat zero-scale-platform keys
- zero-scale-ctl doctor (read-only) and init (diff, confirm or --yes)
- DB provisioning goes through per-operator adapters; SQL travels on stdin,
  the MySQL admin password is read from a Secret and sent on stdin, and
  identifiers and passwords are validated
- Postgres endpoint now names the namespace the cluster is in (was the app's)
- Redis service, ingress class and config-file DB hosts come from the platform
- Legacy fallback with a warning when no platform ConfigMap exists
2026-10-27 06:44:55 -04:00

59 lines
1.9 KiB
Go

package platform
import (
"strings"
"testing"
)
func TestPostgresProvisionSQL(t *testing.T) {
sql, err := PostgresProvisionSQL("db_fdm_1a2b3c4d", "u_fdm_1a2b3c4d", "Secret123", Owner{App: "fdm", Namespace: "qa", Env: "qa"})
if err != nil {
t.Fatal(err)
}
for _, want := range []string{
`CREATE ROLE "u_fdm_1a2b3c4d" WITH LOGIN PASSWORD 'Secret123'`,
`format('CREATE DATABASE %I OWNER %I', 'db_fdm_1a2b3c4d', 'u_fdm_1a2b3c4d')`,
`\gexec`,
`COMMENT ON DATABASE "db_fdm_1a2b3c4d" IS 'zero-scale: env=qa namespace=qa app=fdm'`,
} {
if !strings.Contains(sql, want) {
t.Errorf("missing %q in:\n%s", want, sql)
}
}
}
func TestRejectsUnsafeInput(t *testing.T) {
if _, err := PostgresProvisionSQL(`db"; DROP`, "u", "Secret123", Owner{}); err == nil {
t.Error("expected identifier error")
}
if _, err := PostgresProvisionSQL("db", "u", "it's$$bad", Owner{}); err == nil {
t.Error("expected password error")
}
if _, err := MySQLProvisionSQL("db", "u", "short"); err == nil {
t.Error("expected password length error")
}
if _, err := PostgresProvisionSQL("db", "u", "Secret123", Owner{App: "a'b"}); err == nil {
t.Error("expected owner error")
}
}
func TestPostgresDropSQLChecksOwner(t *testing.T) {
sql, err := PostgresDropSQL("db_x", "u_x", Owner{App: "x", Namespace: "feat-1", Env: "feat-1"})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(sql, "shobj_description(d.oid, 'pg_database') = 'zero-scale: env=feat-1 namespace=feat-1 app=x'") {
t.Errorf("drop not guarded by owner comment:\n%s", sql)
}
}
func TestMySQLClientScriptKeepsPasswordOutOfArgv(t *testing.T) {
s := MySQLClientScript("mysql-ha-haproxy.databases.svc.cluster.local", "3306", "root")
if !strings.HasPrefix(s, "read -r MYSQL_PWD;") || strings.Contains(s, "-p") {
t.Errorf("script = %s", s)
}
if got := shellQuote("a'b"); got != `'a'\''b'` {
t.Errorf("shellQuote = %s", got)
}
}