| 1934 | } |
| 1935 | |
| 1936 | func TestConcurrent(t *testing.T) { |
| 1937 | if enabled, _ := readBool(os.Getenv("MYSQL_TEST_CONCURRENT")); !enabled { |
| 1938 | t.Skip("MYSQL_TEST_CONCURRENT env var not set") |
| 1939 | } |
| 1940 | |
| 1941 | runTests(t, dsn, func(dbt *DBTest) { |
| 1942 | // var version string |
| 1943 | // if err := dbt.db.QueryRow("SELECT @@version").Scan(&version); err != nil { |
| 1944 | // dbt.Fatal(err) |
| 1945 | // } |
| 1946 | // if strings.Contains(strings.ToLower(version), "mariadb") { |
| 1947 | // t.Skip(`TODO: "fix commands out of sync. Did you run multiple statements at once?" on MariaDB`) |
| 1948 | // } |
| 1949 | |
| 1950 | var max int |
| 1951 | err := dbt.db.QueryRow("SELECT @@max_connections").Scan(&max) |
| 1952 | if err != nil { |
| 1953 | dbt.Fatalf("%s", err.Error()) |
| 1954 | } |
| 1955 | dbt.Logf("testing up to %d concurrent connections \r\n", max) |
| 1956 | |
| 1957 | var remaining, succeeded int32 = int32(max), 0 |
| 1958 | |
| 1959 | var wg sync.WaitGroup |
| 1960 | wg.Add(max) |
| 1961 | |
| 1962 | var fatalError string |
| 1963 | var once sync.Once |
| 1964 | fatalf := func(s string, vals ...any) { |
| 1965 | once.Do(func() { |
| 1966 | fatalError = fmt.Sprintf(s, vals...) |
| 1967 | }) |
| 1968 | } |
| 1969 | |
| 1970 | for i := range max { |
| 1971 | go func(id int) { |
| 1972 | defer wg.Done() |
| 1973 | |
| 1974 | tx, err := dbt.db.Begin() |
| 1975 | |
| 1976 | if err != nil { |
| 1977 | if err.Error() != "Error 1040: Too many connections" { |
| 1978 | fatalf("error on conn %d: %s", id, err.Error()) |
| 1979 | } |
| 1980 | return |
| 1981 | } |
| 1982 | |
| 1983 | // keep the connection busy until all connections are open |
| 1984 | for atomic.AddInt32(&remaining, -1) > 0 { |
| 1985 | if _, err = tx.Exec("DO 1"); err != nil { |
| 1986 | fatalf("error on conn %d: %s", id, err.Error()) |
| 1987 | return |
| 1988 | } |
| 1989 | } |
| 1990 | |
| 1991 | if err = tx.Commit(); err != nil { |
| 1992 | fatalf("error on conn %d: %s", id, err.Error()) |
| 1993 | return |