-
Notifications
You must be signed in to change notification settings - Fork 2
Add ProxySQL provider with config generation and binary detection #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package proxysql | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "strings" | ||
| ) | ||
|
|
||
| type BackendServer struct { | ||
| Host string | ||
| Port int | ||
| Hostgroup int | ||
| MaxConns int | ||
| } | ||
|
|
||
| type ProxySQLConfig struct { | ||
| AdminHost string | ||
| AdminPort int | ||
| AdminUser string | ||
| AdminPassword string | ||
| MySQLPort int | ||
| DataDir string | ||
| Backends []BackendServer | ||
| MonitorUser string | ||
| MonitorPass string | ||
| } | ||
|
|
||
| func GenerateConfig(cfg ProxySQLConfig) string { | ||
| var b strings.Builder | ||
|
|
||
| b.WriteString(fmt.Sprintf("datadir=\"%s\"\n\n", cfg.DataDir)) | ||
|
|
||
| b.WriteString("admin_variables=\n{\n") | ||
| b.WriteString(fmt.Sprintf(" admin_credentials=\"%s:%s\"\n", cfg.AdminUser, cfg.AdminPassword)) | ||
| b.WriteString(fmt.Sprintf(" mysql_ifaces=\"%s:%d\"\n", cfg.AdminHost, cfg.AdminPort)) | ||
| b.WriteString("}\n\n") | ||
|
|
||
| b.WriteString("mysql_variables=\n{\n") | ||
| b.WriteString(fmt.Sprintf(" interfaces=\"%s:%d\"\n", cfg.AdminHost, cfg.MySQLPort)) | ||
| b.WriteString(fmt.Sprintf(" monitor_username=\"%s\"\n", cfg.MonitorUser)) | ||
| b.WriteString(fmt.Sprintf(" monitor_password=\"%s\"\n", cfg.MonitorPass)) | ||
| b.WriteString(" monitor_connect_interval=2000\n") | ||
| b.WriteString(" monitor_ping_interval=2000\n") | ||
| b.WriteString("}\n\n") | ||
|
|
||
| if len(cfg.Backends) > 0 { | ||
| b.WriteString("mysql_servers=\n(\n") | ||
| for i, srv := range cfg.Backends { | ||
| b.WriteString(" {\n") | ||
| b.WriteString(fmt.Sprintf(" address=\"%s\"\n", srv.Host)) | ||
| b.WriteString(fmt.Sprintf(" port=%d\n", srv.Port)) | ||
| b.WriteString(fmt.Sprintf(" hostgroup=%d\n", srv.Hostgroup)) | ||
| maxConns := srv.MaxConns | ||
| if maxConns == 0 { | ||
| maxConns = 200 | ||
| } | ||
| b.WriteString(fmt.Sprintf(" max_connections=%d\n", maxConns)) | ||
| b.WriteString(" }") | ||
| if i < len(cfg.Backends)-1 { | ||
| b.WriteString(",") | ||
| } | ||
| b.WriteString("\n") | ||
| } | ||
| b.WriteString(")\n\n") | ||
| } | ||
|
|
||
| b.WriteString("mysql_users=\n(\n") | ||
| b.WriteString(" {\n") | ||
| b.WriteString(fmt.Sprintf(" username=\"%s\"\n", cfg.MonitorUser)) | ||
| b.WriteString(fmt.Sprintf(" password=\"%s\"\n", cfg.MonitorPass)) | ||
| b.WriteString(" default_hostgroup=0\n") | ||
| b.WriteString(" }\n") | ||
| b.WriteString(")\n") | ||
|
|
||
| return b.String() | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package proxysql | ||
|
|
||
| import ( | ||
| "strings" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestGenerateConfigBasic(t *testing.T) { | ||
| cfg := ProxySQLConfig{ | ||
| AdminHost: "127.0.0.1", AdminPort: 6032, | ||
| AdminUser: "admin", AdminPassword: "admin", | ||
| MySQLPort: 6033, DataDir: "/tmp/test", | ||
| MonitorUser: "msandbox", MonitorPass: "msandbox", | ||
| } | ||
| result := GenerateConfig(cfg) | ||
| checks := []string{ | ||
| `admin_credentials="admin:admin"`, | ||
| `interfaces="127.0.0.1:6033"`, | ||
| `monitor_username="msandbox"`, | ||
| `mysql_ifaces="127.0.0.1:6032"`, | ||
| } | ||
| for _, check := range checks { | ||
| if !strings.Contains(result, check) { | ||
| t.Errorf("missing %q in config output", check) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestGenerateConfigWithBackends(t *testing.T) { | ||
| cfg := ProxySQLConfig{ | ||
| AdminHost: "127.0.0.1", AdminPort: 6032, | ||
| AdminUser: "admin", AdminPassword: "admin", | ||
| MySQLPort: 6033, DataDir: "/tmp/test", | ||
| MonitorUser: "msandbox", MonitorPass: "msandbox", | ||
| Backends: []BackendServer{ | ||
| {Host: "127.0.0.1", Port: 3306, Hostgroup: 0, MaxConns: 100}, | ||
| {Host: "127.0.0.1", Port: 3307, Hostgroup: 1, MaxConns: 100}, | ||
| }, | ||
| } | ||
| result := GenerateConfig(cfg) | ||
| if !strings.Contains(result, "mysql_servers=") { | ||
| t.Error("missing mysql_servers section") | ||
| } | ||
| if !strings.Contains(result, "port=3306") { | ||
| t.Error("missing first backend") | ||
| } | ||
| if !strings.Contains(result, "hostgroup=1") { | ||
| t.Error("missing reader hostgroup") | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,167 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package proxysql | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os/exec" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strconv" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/ProxySQL/dbdeployer/providers" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ProviderName = "proxysql" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type ProxySQLProvider struct{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewProxySQLProvider() *ProxySQLProvider { return &ProxySQLProvider{} } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *ProxySQLProvider) Name() string { return ProviderName } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *ProxySQLProvider) ValidateVersion(version string) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts := strings.Split(version, ".") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(parts) < 2 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid ProxySQL version format: %q (expected X.Y or X.Y.Z)", version) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *ProxySQLProvider) DefaultPorts() providers.PortRange { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return providers.PortRange{BasePort: 6032, PortsPerInstance: 2} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *ProxySQLProvider) FindBinary(version string) (string, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path, err := exec.LookPath("proxysql") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "", fmt.Errorf("proxysql binary not found in PATH: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return path, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *ProxySQLProvider) CreateSandbox(config providers.SandboxConfig) (*providers.SandboxInfo, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| binaryPath, err := p.FindBinary(config.Version) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dataDir := filepath.Join(config.Dir, "data") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := os.MkdirAll(dataDir, 0755); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("creating data directory: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adminPort := config.AdminPort | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if adminPort == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adminPort = config.Port | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mysqlPort := adminPort + 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+54
to
+57
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if adminPort == 0 { | |
| adminPort = config.Port | |
| } | |
| mysqlPort := adminPort + 1 | |
| mysqlPort := config.Port | |
| // Ensure ports follow documented semantics: | |
| // - config.Port is the primary/MySQL listener (default 6033) | |
| // - config.AdminPort is the management/admin interface (default 6032) | |
| // Derive the missing one if only one is provided, or use defaults if both are zero. | |
| if adminPort == 0 && mysqlPort == 0 { | |
| // Neither port provided: fall back to provider defaults (6032 admin, 6033 MySQL). | |
| defaultPorts := p.DefaultPorts() | |
| adminPort = defaultPorts.BasePort | |
| mysqlPort = adminPort + 1 | |
| } else { | |
| if adminPort == 0 { | |
| // Only MySQL port provided: derive admin port just below it. | |
| adminPort = mysqlPort - 1 | |
| } else if mysqlPort == 0 { | |
| // Only admin port provided: derive MySQL port just above it. | |
| mysqlPort = adminPort + 1 | |
| } | |
| } |
Check failure on line 96 in providers/proxysql/proxysql.go
GitHub Actions / Lint
G306: Expect WriteFile permissions to be 0600 or less (gosec)
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generated config contains admin/monitor credentials but is written with mode 0644, making it world-readable on multi-user systems. Use a more restrictive permission (e.g., 0600) or avoid writing secrets into the config when possible.
| if err := os.WriteFile(cfgPath, []byte(cfgContent), 0644); err != nil { | |
| if err := os.WriteFile(cfgPath, []byte(cfgContent), 0600); err != nil { |
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The start script always runs ProxySQL with --initial. ProxySQL uses --initial to reset/empty the on-disk SQLite DB in the datadir, so using it on every start will discard persisted config on restarts. The start script should only use --initial for first bootstrap (e.g., when the DB file doesn't exist), and do normal starts without it thereafter.
| "start": fmt.Sprintf("#!/bin/bash\ncd %s\n%s --initial -c %s -D %s &\nSBPID=$!\necho $SBPID > %s/proxysql.pid\nsleep 2\nif kill -0 $SBPID 2>/dev/null; then\n echo 'ProxySQL started (pid '$SBPID')'\nelse\n echo 'ProxySQL failed to start'\n exit 1\nfi\n", | |
| config.Dir, binaryPath, cfgPath, dataDir, config.Dir), | |
| "start": fmt.Sprintf("#!/bin/bash\ncd %s\nDBFILE=%s/proxysql.db\nINITIAL=\"\"\nif [ ! -f \"$DBFILE\" ]; then\n INITIAL=\"--initial\"\nfi\n%s $INITIAL -c %s -D %s &\nSBPID=$!\necho $SBPID > %s/proxysql.pid\nsleep 2\nif kill -0 $SBPID 2>/dev/null; then\n echo 'ProxySQL started (pid '$SBPID')'\nelse\n echo 'ProxySQL failed to start'\n exit 1\nfi\n", | |
| config.Dir, dataDir, binaryPath, cfgPath, dataDir, config.Dir), |
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generated shell scripts interpolate paths (cd <dir>, binaryPath, cfgPath, dataDir, PIDFILE) without any quoting/escaping. If the sandbox dir or binary path contains spaces or shell metacharacters, the scripts can break or behave unexpectedly. Consider shell-escaping/quoting these interpolated values consistently.
| "start": fmt.Sprintf("#!/bin/bash\ncd %s\n%s --initial -c %s -D %s &\nSBPID=$!\necho $SBPID > %s/proxysql.pid\nsleep 2\nif kill -0 $SBPID 2>/dev/null; then\n echo 'ProxySQL started (pid '$SBPID')'\nelse\n echo 'ProxySQL failed to start'\n exit 1\nfi\n", | |
| config.Dir, binaryPath, cfgPath, dataDir, config.Dir), | |
| "stop": fmt.Sprintf("#!/bin/bash\nPIDFILE=%s/proxysql.pid\nif [ -f $PIDFILE ]; then\n PID=$(cat $PIDFILE)\n kill $PID 2>/dev/null\n sleep 1\n kill -0 $PID 2>/dev/null && kill -9 $PID 2>/dev/null\n rm -f $PIDFILE\n echo 'ProxySQL stopped'\nelse\n echo 'ProxySQL not running (no pid file)'\nfi\n", | |
| config.Dir), | |
| "status": fmt.Sprintf("#!/bin/bash\nPIDFILE=%s/proxysql.pid\nif [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE) 2>/dev/null; then\n echo 'ProxySQL running (pid '$(cat $PIDFILE)')'\nelse\n echo 'ProxySQL not running'\n exit 1\nfi\n", | |
| "start": fmt.Sprintf("#!/bin/bash\ncd \"%s\"\n\"%s\" --initial -c \"%s\" -D \"%s\" &\nSBPID=$!\necho \"$SBPID\" > \"%s/proxysql.pid\"\nsleep 2\nif kill -0 \"$SBPID\" 2>/dev/null; then\n echo 'ProxySQL started (pid '$SBPID')'\nelse\n echo 'ProxySQL failed to start'\n exit 1\nfi\n", | |
| config.Dir, binaryPath, cfgPath, dataDir, config.Dir), | |
| "stop": fmt.Sprintf("#!/bin/bash\nPIDFILE=\"%s/proxysql.pid\"\nif [ -f \"$PIDFILE\" ]; then\n PID=$(cat \"$PIDFILE\")\n kill \"$PID\" 2>/dev/null\n sleep 1\n kill -0 \"$PID\" 2>/dev/null && kill -9 \"$PID\" 2>/dev/null\n rm -f \"$PIDFILE\"\n echo 'ProxySQL stopped'\nelse\n echo 'ProxySQL not running (no pid file)'\nfi\n", | |
| config.Dir), | |
| "status": fmt.Sprintf("#!/bin/bash\nPIDFILE=\"%s/proxysql.pid\"\nif [ -f \"$PIDFILE\" ] && kill -0 \"$(cat \"$PIDFILE\")\" 2>/dev/null; then\n echo 'ProxySQL running (pid '$(cat \"$PIDFILE\")')'\nelse\n echo 'ProxySQL not running'\n exit 1\nfi\n", |
Check failure on line 116 in providers/proxysql/proxysql.go
GitHub Actions / Lint
G306: Expect WriteFile permissions to be 0600 or less (gosec)
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generated use/use_proxy scripts embed passwords directly on the mysql client command line (-p<pass>), which can leak via process listings and are also stored in world-readable executable files (0755). Prefer prompting for the password, using a restricted-permission defaults file (e.g., my.proxy.cnf mode 0600), or passing creds via environment with tight file perms (and consider 0700 for the scripts directory/files).
| "use_proxy": fmt.Sprintf("#!/bin/bash\nmysql -h %s -P %d -u %s -p%s --prompt 'ProxySQL> ' \"$@\"\n", | |
| host, mysqlPort, monitorUser, monitorPass), | |
| } | |
| for name, content := range scripts { | |
| scriptPath := filepath.Join(config.Dir, name) | |
| if err := os.WriteFile(scriptPath, []byte(content), 0755); err != nil { | |
| "use_proxy": fmt.Sprintf("#!/bin/bash\nmysql -h %s -P %d -u %s --prompt 'ProxySQL> ' \"$@\"\n", | |
| host, mysqlPort, monitorUser), | |
| } | |
| for name, content := range scripts { | |
| scriptPath := filepath.Join(config.Dir, name) | |
| if err := os.WriteFile(scriptPath, []byte(content), 0700); err != nil { |
Check failure on line 129 in providers/proxysql/proxysql.go
GitHub Actions / Lint
G204: Subprocess launched with a potential tainted input or cmd arguments (gosec)
Check failure on line 138 in providers/proxysql/proxysql.go
GitHub Actions / Lint
G204: Subprocess launched with a potential tainted input or cmd arguments (gosec)
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseBackends silently ignores malformed backend entries and ignores Atoi errors (defaulting port/hostgroup to 0). This can generate an invalid config without surfacing an error to the user. Consider validating each entry (exactly 3 fields, successful int parses, port>0, hostgroup>=0) and either returning an error from CreateSandbox or skipping invalid entries with a clear warning/error message.
| parts := strings.Split(entry, ":") | |
| if len(parts) >= 3 { | |
| port, _ := strconv.Atoi(parts[1]) | |
| hg, _ := strconv.Atoi(parts[2]) | |
| backends = append(backends, BackendServer{ | |
| Host: parts[0], Port: port, Hostgroup: hg, MaxConns: 200, | |
| }) | |
| } | |
| entry = strings.TrimSpace(entry) | |
| if entry == "" { | |
| continue | |
| } | |
| parts := strings.Split(entry, ":") | |
| if len(parts) != 3 { | |
| fmt.Fprintf(os.Stderr, "proxysql: ignoring invalid backend %q (expected host:port:hostgroup)\n", entry) | |
| continue | |
| } | |
| host := strings.TrimSpace(parts[0]) | |
| if host == "" { | |
| fmt.Fprintf(os.Stderr, "proxysql: ignoring backend %q with empty host\n", entry) | |
| continue | |
| } | |
| port, err := strconv.Atoi(strings.TrimSpace(parts[1])) | |
| if err != nil || port <= 0 { | |
| fmt.Fprintf(os.Stderr, "proxysql: ignoring backend %q with invalid port %q\n", entry, parts[1]) | |
| continue | |
| } | |
| hg, err := strconv.Atoi(strings.TrimSpace(parts[2])) | |
| if err != nil || hg < 0 { | |
| fmt.Fprintf(os.Stderr, "proxysql: ignoring backend %q with invalid hostgroup %q\n", entry, parts[2]) | |
| continue | |
| } | |
| backends = append(backends, BackendServer{ | |
| Host: host, Port: port, Hostgroup: hg, MaxConns: 200, | |
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package proxysql | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ProxySQL/dbdeployer/providers" | ||
| ) | ||
|
|
||
| func TestProxySQLProviderName(t *testing.T) { | ||
| p := NewProxySQLProvider() | ||
| if p.Name() != "proxysql" { | ||
| t.Errorf("expected 'proxysql', got %q", p.Name()) | ||
| } | ||
| } | ||
|
|
||
| func TestProxySQLProviderValidateVersion(t *testing.T) { | ||
| p := NewProxySQLProvider() | ||
| tests := []struct { | ||
| version string | ||
| wantErr bool | ||
| }{ | ||
| {"2.7.0", false}, | ||
| {"3.0.0", false}, | ||
| {"invalid", true}, | ||
| } | ||
| for _, tt := range tests { | ||
| err := p.ValidateVersion(tt.version) | ||
| if (err != nil) != tt.wantErr { | ||
| t.Errorf("ValidateVersion(%q) error = %v, wantErr %v", tt.version, err, tt.wantErr) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestProxySQLProviderRegister(t *testing.T) { | ||
| reg := providers.NewRegistry() | ||
| if err := Register(reg); err != nil { | ||
| t.Fatalf("Register failed: %v", err) | ||
| } | ||
| p, err := reg.Get("proxysql") | ||
| if err != nil { | ||
| t.Fatalf("Get failed: %v", err) | ||
| } | ||
| if p.Name() != "proxysql" { | ||
| t.Errorf("expected 'proxysql', got %q", p.Name()) | ||
| } | ||
| } | ||
|
|
||
| func TestProxySQLFindBinary(t *testing.T) { | ||
| p := NewProxySQLProvider() | ||
| path, err := p.FindBinary("2.7.0") | ||
| if err != nil { | ||
| t.Skipf("proxysql not installed, skipping: %v", err) | ||
| } | ||
| if path == "" { | ||
| t.Error("expected non-empty path") | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ignores any error from ProxySQL provider registration.
Registry.Registeronly errors on programming/configuration issues (e.g., duplicate provider name), not on missing binaries, so swallowing the error could hide a real startup bug. Consider handling the error explicitly (e.g., print a warning to stderr) while still keeping it non-fatal.