Files
dobotai-platform/scripts/containerized_deployment_test.go
T
2026-09-11 17:27:20 +08:00

99 lines
3.7 KiB
Go

package scripts
import (
"os"
"strings"
"testing"
)
func TestDockerDeploymentContainsOnlyDobotAIApplication(t *testing.T) {
compose, err := os.ReadFile("../deploy/dobotai-dingtalk/compose.yaml")
if err != nil {
t.Fatal(err)
}
source := string(compose)
for _, required := range []string{"dobotai-dingtalk:", "container_name: dobotai-dingtalk", "network_mode: host", "env_file:", "read_only: true"} {
if !strings.Contains(source, required) {
t.Errorf("compose missing %q", required)
}
}
for _, forbidden := range []string{"dobotai-postgres", "postgres-data", "name: dobotai-network"} {
if strings.Contains(source, forbidden) {
t.Errorf("compose must not manage a local database resource %q", forbidden)
}
}
}
func TestRootInstallerBuildsImageWithoutOperatorImageArgument(t *testing.T) {
data, err := os.ReadFile("../install-docker.sh")
if err != nil {
t.Fatal(err)
}
source := string(data)
for _, required := range []string{"docker build", "dobotai-dingtalk:local-", "install_docker_if_missing", "DOBOTAI_SOURCE_ROOT", "deploy/dobotai-dingtalk/install-docker.sh"} {
if !strings.Contains(source, required) {
t.Errorf("root installer missing %q", required)
}
}
if strings.Contains(source, "${DOBOTAI_IMAGE") {
t.Fatal("root installer must not require DOBOTAI_IMAGE")
}
}
func TestDockerfilePropagatesConfiguredGoProxyToModuleDownload(t *testing.T) {
data, err := os.ReadFile("../Dockerfile")
if err != nil {
t.Fatal(err)
}
source := string(data)
for _, required := range []string{"ARG GOPROXY=", "ENV GOPROXY=${GOPROXY}", "RUN go mod download"} {
if !strings.Contains(source, required) {
t.Errorf("Dockerfile missing %q", required)
}
}
if !(strings.Index(source, "ENV GOPROXY=${GOPROXY}") < strings.Index(source, "RUN go mod download")) {
t.Fatal("Dockerfile must set GOPROXY before downloading modules")
}
}
func TestRDSInitializerOnlyInitializesEmptySchemaAndRejectsInconsistentSchema(t *testing.T) {
data, err := os.ReadFile("../deploy/dobotai-dingtalk/rds-schema-init.sh")
if err != nil {
t.Fatal(err)
}
source := string(data)
for _, required := range []string{"pg_isready", "to_regclass('public.turns')", "empty", "normal", "inconsistent", "数据库不存在", "*.up.sql", "DATABASE_URL", "postgres:16-alpine"} {
if !strings.Contains(source, required) {
t.Errorf("RDS initializer missing %q", required)
}
}
for _, forbidden := range []string{"docker compose", "dobotai-postgres", "pg_dump -Fc", "DROP DATABASE", "DROP SCHEMA"} {
if strings.Contains(source, forbidden) {
t.Errorf("RDS initializer must not manage or destroy databases: %q", forbidden)
}
}
}
func TestRDSCredentialConfiguratorPromptsForExternalDatabase(t *testing.T) {
data, err := os.ReadFile("../deploy/dobotai-dingtalk/configure_env.py")
if err != nil {
t.Fatal(err)
}
source := string(data)
for _, required := range []string{"DATABASE_URL", "阿里云RDS", "快速问答Agent ID", "智能推理Agent ID", "getpass.getpass", "os.replace", "0o600"} {
if !strings.Contains(source, required) {
t.Errorf("RDS configurator missing %q", required)
}
}
if strings.Contains(source, "DobotAI租户键") || strings.Contains(source, "Agent Bindings JSON") || strings.Contains(source, "DobotAI Ingress Token") {
t.Fatal("operator must only be prompted for real RDS, WeKnora and DingTalk configuration")
}
installer, err := os.ReadFile("../deploy/dobotai-dingtalk/install-docker.sh")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(installer), "secrets.token_hex") || !strings.Contains(string(installer), "secrets.token_urlsafe") || !strings.Contains(string(installer), "DOBOTAI_TENANT_KEY=dobotai-") {
t.Fatal("installer must generate and persist internal tenant and ingress tokens")
}
}