76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
//go:build mysql
|
|
|
|
package mysql
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
mysqldriver "github.com/go-sql-driver/mysql"
|
|
)
|
|
|
|
func TestLoginAuditQueriesAreTenantScoped(t *testing.T) {
|
|
source, err := os.ReadFile("tenant_security_audit.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body := string(source)
|
|
for _, required := range []string{
|
|
"(tenant_id,user_id,username",
|
|
"(tenant_id,user_id,account_type",
|
|
"WHERE tenant_id=? AND session_id=?",
|
|
} {
|
|
if !strings.Contains(body, required) {
|
|
t.Fatalf("login audit query is missing tenant scope %q", required)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRetryMySQLDeadlockEventuallySucceeds(t *testing.T) {
|
|
calls := 0
|
|
var delays []time.Duration
|
|
err := retryMySQLDeadlock(func() error {
|
|
calls++
|
|
if calls < 3 {
|
|
return &mysqldriver.MySQLError{Number: 1213, SQLState: [5]byte{'4', '0', '0', '0', '1'}}
|
|
}
|
|
return nil
|
|
}, func(delay time.Duration) { delays = append(delays, delay) })
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if calls != 3 {
|
|
t.Fatalf("operation calls=%d want=3", calls)
|
|
}
|
|
want := []time.Duration{25 * time.Millisecond, 50 * time.Millisecond}
|
|
if len(delays) != len(want) || delays[0] != want[0] || delays[1] != want[1] {
|
|
t.Fatalf("retry delays=%v want=%v", delays, want)
|
|
}
|
|
}
|
|
|
|
func TestRetryMySQLDeadlockStopsOnNonRetryableError(t *testing.T) {
|
|
want := errors.New("invalid update")
|
|
calls := 0
|
|
err := retryMySQLDeadlock(func() error {
|
|
calls++
|
|
return want
|
|
}, func(time.Duration) { t.Fatal("non-retryable error must not sleep") })
|
|
if !errors.Is(err, want) || calls != 1 {
|
|
t.Fatalf("err=%v calls=%d want=%v/1", err, calls, want)
|
|
}
|
|
}
|
|
|
|
func TestRetryMySQLDeadlockStopsAfterFourAttempts(t *testing.T) {
|
|
calls := 0
|
|
err := retryMySQLDeadlock(func() error {
|
|
calls++
|
|
return &mysqldriver.MySQLError{Number: 1205}
|
|
}, func(time.Duration) {})
|
|
if err == nil || calls != 4 {
|
|
t.Fatalf("err=%v calls=%d want non-nil/4", err, calls)
|
|
}
|
|
}
|