Files
opsxdb/server/internal/aitools/policy_test.go
T
logan 2c0bfafd8d 同步完整源码至远程:扁平化重构现状 + 未入库源文件
- 补入库:server/internal/db/dump.go、redis 分页/扫描预算测试、opsxdb-mcp main_test、
  packages/opsxdb-mcp package-lock、docs 审计与对比文档等 37 个新文件
- 含结构扁平化进行中的 80 处修改与 155 处旧结构删除(server/ src/ src-tauri/ 为当前有效源)
- 构建产物(bin/target/dist)与签名私钥仍按规则排除
2026-10-16 03:47:33 +08:00

95 lines
2.7 KiB
Go

package aitools
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)
func TestSaveLoadPolicyRoundTrip(t *testing.T) {
dir := t.TempDir()
t.Setenv("HOME", dir)
// PolicyPath uses UserHomeDir → ~/.opsxdb/mcp.json
p := Policy{
AllowedConnectionIDs: []string{" a ", "b", "a", ""},
Mode: "READ_WRITE",
AllowDangerous: true,
DefaultLimit: 50,
MaxLimit: 200,
}
if err := SavePolicy(p); err != nil {
t.Fatal(err)
}
path := filepath.Join(dir, ".opsxdb", "mcp.json")
if _, err := os.Stat(path); err != nil {
t.Fatal(err)
}
got, err := LoadPolicy()
if err != nil {
t.Fatal(err)
}
if got.Mode != ModeReadWrite {
t.Fatalf("mode=%s", got.Mode)
}
if !got.AllowDangerous {
t.Fatal("want allow_dangerous")
}
if len(got.AllowedConnectionIDs) != 2 || got.AllowedConnectionIDs[0] != "a" || got.AllowedConnectionIDs[1] != "b" {
t.Fatalf("ids=%v", got.AllowedConnectionIDs)
}
if got.DefaultLimit != 50 || got.MaxLimit != 200 {
t.Fatalf("limits %d/%d", got.DefaultLimit, got.MaxLimit)
}
}
func TestDangerousSQLRequiresAllowFlag(t *testing.T) {
rt := NewRuntime(Policy{
AllowedConnectionIDs: []string{"c1"},
Mode: ModeReadWrite,
AllowDangerous: false,
})
rt.FindConn = func(id string) (*SavedConnection, error) {
return &SavedConnection{ID: id, Name: "c1", Driver: "mysql", Host: "127.0.0.1", Port: 3306}, nil
}
rt.Audit = func(AuditEntry) {}
rt.AllowConfirmedWrite = true
_, err := rt.Call(context.Background(), ToolExecuteQuery, map[string]any{
"connection_id": "c1",
"sql": "DROP TABLE users",
"confirm_danger": true,
})
if err == nil || !contains(err.Error(), "dangerous sql disabled") {
t.Fatalf("want dangerous disabled, got %v", err)
}
}
func TestDefaultWritePolicyStillRequiresConfirmation(t *testing.T) {
p := DefaultPolicy()
if !p.WritesEnabled() || !p.AllowsDangerousDDL() {
t.Fatal("新配置应默认允许读写和危险 SQL")
}
if err := p.AllowConnection("c1"); err == nil {
t.Fatal("默认权限不能自动授权连接")
}
p.AllowedConnectionIDs = []string{"c1"}
rt := NewRuntime(p)
rt.RejectCallerConfirm = true
rt.Audit = func(AuditEntry) {}
rt.FindConn = func(id string) (*SavedConnection, error) {
return &SavedConnection{ID: id, Driver: "mysql"}, nil
}
out, err := rt.Call(context.Background(), ToolExecuteQuery, map[string]any{
"connection_id": "c1", "sql": "DROP TABLE demo", "confirm_danger": true,
})
if err != nil {
t.Fatal(err)
}
if out.(map[string]any)["needConfirm"] != true {
t.Fatalf("默认允许危险 SQL 后,Agent 仍必须等待用户确认: %v", out)
}
}
func contains(s, sub string) bool { return strings.Contains(s, sub) }