Files
dobotai-platform/scripts/containerized_deployment_test.go

118 lines
3.5 KiB
Go

package scripts
import (
"os"
"strings"
"testing"
)
func TestDobotAIDingTalkContainerAssetsProvideSafeShortOperatorCommands(t *testing.T) {
compose, err := os.ReadFile("../deploy/dobotai-dingtalk/compose.yaml")
if err != nil {
t.Fatal(err)
}
for _, required := range []string{
"dobotai-dingtalk:",
"container_name: dobotai-dingtalk",
"network_mode: host",
"env_file:",
"read_only: true",
"/var/lib/dobotai/secrets",
} {
if !strings.Contains(string(compose), required) {
t.Errorf("compose missing %q", required)
}
}
configure, err := os.ReadFile("../deploy/dobotai-dingtalk/dobotai-dingtalk-configure")
if err != nil {
t.Fatal(err)
}
for _, required := range []string{
"configure_env.py",
"/etc/dobotai-test/dobotai.env",
"dobotai-dingtalk-start",
} {
if !strings.Contains(string(configure), required) {
t.Errorf("configure command missing %q", required)
}
}
bind, err := os.ReadFile("../deploy/dobotai-dingtalk/dobotai-dingtalk-bind-admin")
if err != nil {
t.Fatal(err)
}
for _, required := range []string{
"docker exec -it dobotai-dingtalk",
"/usr/local/bin/dobotai bootstrap-admin",
} {
if !strings.Contains(string(bind), required) {
t.Errorf("bind command missing %q", required)
}
}
}
func TestDobotAIDingTalkCredentialConfigurationNeverPassesSecretsOnCommandLine(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{"getpass.getpass", "os.replace", "0o600", "DINGTALK_CLIENT_SECRET"} {
if !strings.Contains(source, required) {
t.Errorf("credential configurator missing %q", required)
}
}
for _, forbidden := range []string{"subprocess.run([", "-v", "DINGTALK_CLIENT_SECRET="} {
if strings.Contains(source, forbidden) {
t.Errorf("credential configurator must not expose secret through process arguments: %q", forbidden)
}
}
}
func TestDobotAIDingTalkCredentialConfigurationExplainsEveryInputWithRedactedExamples(t *testing.T) {
configurator, err := os.ReadFile("../deploy/dobotai-dingtalk/configure_env.py")
if err != nil {
t.Fatal(err)
}
documentation, err := os.ReadFile("../deploy/dobotai-dingtalk/README.md")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(configurator), "格式示例:{example}") || !strings.Contains(string(documentation), "格式示例") {
t.Fatal("configuration guidance must label every example")
}
for _, example := range []string{
"postgres://USER:<数据库密码>@127.0.0.1:55432/dobotai_test?sslmode=disable",
"http://127.0.0.1:8080",
`{"dingtalk:*":"你的Agent ID"}`,
"DINGTALK_CLIENT_SECRET",
} {
if !strings.Contains(string(configurator), example) {
t.Errorf("configurator missing redacted example %q", example)
}
if !strings.Contains(string(documentation), example) {
t.Errorf("documentation missing redacted example %q", example)
}
}
}
func TestDobotAIDingTalkStartRollsBackToPreviousContainerImage(t *testing.T) {
data, err := os.ReadFile("../deploy/dobotai-dingtalk/dobotai-dingtalk-start")
if err != nil {
t.Fatal(err)
}
source := string(data)
for _, required := range []string{
"previous_image=",
"set_runtime_image",
"docker inspect --format",
"set_runtime_image \"$previous_image\"",
"docker compose --env-file \"$runtime_env\" -f \"$compose_file\" up -d --no-build --force-recreate",
} {
if !strings.Contains(source, required) {
t.Errorf("start script missing container upgrade rollback %q", required)
}
}
}