From d95ecfa9a0d2702f441f6eb929596d81df17f623 Mon Sep 17 00:00:00 2001 From: xuans Date: Mon, 28 Sep 2026 00:20:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84MySQL=E5=AE=98=E6=96=B9?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E9=94=99=E8=AF=AF=E7=A0=81=E5=AF=B9?= =?UTF-8?q?=E7=85=A7=E6=B5=8B=E8=AF=95=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仅提取数据库错误码,不输出官方客户端原始错误内容;保留严格TLS连接和凭据隔离。CLI常规测试通过,视图业务改动另行复核。 --- .../internal/testsupport/mysqltest/tools.go | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/backend/internal/testsupport/mysqltest/tools.go b/backend/internal/testsupport/mysqltest/tools.go index f5ddd90..f66d8c6 100644 --- a/backend/internal/testsupport/mysqltest/tools.go +++ b/backend/internal/testsupport/mysqltest/tools.go @@ -1,12 +1,15 @@ package mysqltest import ( + "bytes" "context" "io" "os" "os/exec" "path/filepath" + "regexp" "runtime" + "strconv" "strings" "testing" "time" @@ -54,9 +57,33 @@ func (f *Server) Import(t *testing.T, cfg config.DatabaseConfig, input string) { }, file, io.Discard) } +// 仅返回官方客户端的数据库错误码,不向日志透传可能含业务数据的错误文本。 +func (f *Server) ImportErrorCode(t *testing.T, cfg config.DatabaseConfig, input string) int { + t.Helper() + file, err := os.Open(input) + if err != nil { + t.Fatal(err) + } + defer file.Close() + code, err := f.runToolResult(t, "mysql", cfg, []string{ + "--binary-mode", "--batch", "--skip-reconnect", "--local-infile=0", + }, file, io.Discard) + if err == nil || code == 0 { + t.Fatal("官方客户端未返回预期的数据库错误码,不能作为失败对照") + } + return code +} + func (f *Server) IsMySQL8() bool { return strings.Contains(f.version, "Ver 8.0.") } func (f *Server) runTool(t *testing.T, name string, cfg config.DatabaseConfig, args []string, input io.Reader, output io.Writer) { + t.Helper() + if _, err := f.runToolResult(t, name, cfg, args, input, output); err != nil { + t.Fatalf("官方 %s 执行失败:%v;原始输出已隐藏", name, err) + } +} + +func (f *Server) runToolResult(t *testing.T, name string, cfg config.DatabaseConfig, args []string, input io.Reader, output io.Writer) (int, error) { t.Helper() parsed, err := mysql.ParseDSN(cfg.DSN) if err != nil || cfg.Driver != "mysql" { @@ -93,11 +120,15 @@ func (f *Server) runTool(t *testing.T, name string, cfg config.DatabaseConfig, a command.Env = mysqlToolTestEnvironment(f.root, parsed.Passwd) command.Stdin, command.Stdout = input, output // 错误可能含数据库内容;只报告退出状态,不透传工具的原始错误输出。 - command.Stderr = io.Discard + var stderr bytes.Buffer + command.Stderr = &stderr command.WaitDelay = 2 * time.Second - if err := command.Run(); err != nil { - t.Fatalf("官方 %s 执行失败:%v;原始输出已隐藏", name, err) + err = command.Run() + code := 0 + if match := regexp.MustCompile(`(?m)^ERROR ([0-9]+) \([A-Z0-9]+\)`).FindSubmatch(stderr.Bytes()); len(match) > 1 { + code, _ = strconv.Atoi(string(match[1])) } + return code, err } func mysqlToolTestEnvironment(root, password string) []string {