package repository import ( "crypto/tls" "os" "path/filepath" "strings" "testing" "cmautobuy/admin/config" ) func TestOpenMySQL_公网TLS只读冒烟(t *testing.T) { if os.Getenv("CMAUTOBUY_MYSQL_PUBLIC_TLS_TEST") != "1" { t.Skip("未启用公网 MySQL TLS 冒烟") } cfg, err := config.LoadDatabaseFromEnv() if err != nil { t.Fatal(err) } if cfg.TLSMode != config.DatabaseTLSVerifyCA { t.Fatalf("公网冒烟必须使用 verify_ca,实际 %q", cfg.TLSMode) } db, err := OpenMySQL(cfg) if err != nil { t.Fatal(err) } defer db.Close() var variableName, cipher string if err := db.QueryRow(`SHOW STATUS LIKE 'Ssl_cipher'`).Scan(&variableName, &cipher); err != nil { t.Fatal(err) } if cipher == "" { t.Fatal("公网 MySQL 连接没有协商 TLS cipher") } t.Logf("公网 MySQL TLS 已启用:%s", cipher) } func TestNewMySQLDriverConfig_VerifyCA启用TLS且不回退明文(t *testing.T) { cfg := config.DatabaseConfig{ Host: "185.216.248.75", Port: "3307", Name: "autobuy_test", User: "buy", Password: "test-secret", TLSMode: config.DatabaseTLSVerifyCA, TLSCA: filepath.Join("..", "certs", "mysql84-ca.pem"), } driverConfig, err := newMySQLDriverConfig(cfg) if err != nil { t.Fatal(err) } if driverConfig.TLS == nil { t.Fatal("verify_ca 必须启用 TLS") } if driverConfig.TLS.MinVersion != tls.VersionTLS12 { t.Fatalf("TLS 最低版本=%d,期望 TLS 1.2", driverConfig.TLS.MinVersion) } if driverConfig.TLS.VerifyConnection == nil { t.Fatal("verify_ca 必须安装证书链校验回调") } if driverConfig.AllowFallbackToPlaintext { t.Fatal("公网 TLS 不得回退明文") } } func TestNewMySQLDriverConfig_Disabled保持本机连接兼容(t *testing.T) { cfg := config.DatabaseConfig{ Host: "127.0.0.1", Port: "3307", Name: "autobuy_test", User: "buy", Password: "test-secret", TLSMode: config.DatabaseTLSDisabled, } driverConfig, err := newMySQLDriverConfig(cfg) if err != nil { t.Fatal(err) } if driverConfig.TLS != nil { t.Fatal("disabled 不应改变现有本机连接") } } func TestNewMySQLDriverConfig_CA文件损坏时报明确错误(t *testing.T) { caPath := filepath.Join(t.TempDir(), "broken-ca.pem") if err := os.WriteFile(caPath, []byte("not a certificate"), 0o600); err != nil { t.Fatal(err) } cfg := config.DatabaseConfig{ Host: "185.216.248.75", Port: "3307", Name: "autobuy_test", User: "buy", Password: "test-secret", TLSMode: config.DatabaseTLSVerifyCA, TLSCA: caPath, } _, err := newMySQLDriverConfig(cfg) if err == nil || !strings.Contains(err.Error(), "没有有效 PEM 证书") { t.Fatalf("损坏 CA 应该返回明确错误,实际:%v", err) } }