jet/tests/init/init.go

248 lines
5.6 KiB
Go
Raw Permalink Normal View History

2019-06-11 12:47:35 +02:00
package main
import (
2022-05-05 13:01:42 +02:00
"context"
2019-06-11 12:47:35 +02:00
"database/sql"
"errors"
2019-07-29 18:08:53 +02:00
"flag"
2019-06-21 13:56:57 +02:00
"fmt"
"source.gleipnir.technology/Gleipnir/jet/v2/generator/mysql"
"source.gleipnir.technology/Gleipnir/jet/v2/generator/postgres"
"source.gleipnir.technology/Gleipnir/jet/v2/generator/sqlite"
"source.gleipnir.technology/Gleipnir/jet/v2/internal/utils/errfmt"
"source.gleipnir.technology/Gleipnir/jet/v2/tests/internal/utils/repo"
2021-08-30 15:09:09 +03:00
"os"
"os/exec"
"strings"
"source.gleipnir.technology/Gleipnir/jet/v2/tests/dbconfig"
2019-07-30 11:18:12 +02:00
_ "github.com/go-sql-driver/mysql"
_ "github.com/jackc/pgx/v5/stdlib"
2022-05-05 13:01:42 +02:00
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
2019-06-11 12:47:35 +02:00
)
2019-07-29 18:08:53 +02:00
var testSuite string
func init() {
2022-05-05 13:01:42 +02:00
flag.StringVar(&testSuite, "testsuite", "all", "Test suite name (postgres, mysql, mariadb, cockroach, sqlite or all)")
2019-07-29 18:08:53 +02:00
flag.Parse()
}
// Database names
2022-05-05 13:01:42 +02:00
const (
Postgres = "postgres"
MySql = "mysql"
MariaDB = "mariadb"
Sqlite = "sqlite"
Cockroach = "cockroach"
)
2019-07-29 18:08:53 +02:00
2022-05-05 13:01:42 +02:00
func main() {
2023-07-21 13:20:44 +02:00
var err error
2019-07-29 18:08:53 +02:00
2022-05-05 13:01:42 +02:00
switch strings.ToLower(testSuite) {
case Postgres:
2023-07-21 13:20:44 +02:00
err = initPostgresDB(Postgres, dbconfig.PostgresConnectString)
2022-05-05 13:01:42 +02:00
case Cockroach:
2023-07-21 13:20:44 +02:00
err = initPostgresDB(Cockroach, dbconfig.CockroachConnectString)
2022-05-05 13:01:42 +02:00
case MySql:
2023-07-21 13:20:44 +02:00
err = initMySQLDB(false)
2022-05-05 13:01:42 +02:00
case MariaDB:
2023-07-21 13:20:44 +02:00
err = initMySQLDB(true)
2022-05-05 13:01:42 +02:00
case Sqlite:
2023-07-21 13:20:44 +02:00
err = initSQLiteDB()
2022-05-05 13:01:42 +02:00
case "all":
2023-07-21 13:20:44 +02:00
err = initPostgresDB(Cockroach, dbconfig.CockroachConnectString)
if err != nil {
break
}
err = initPostgresDB(Postgres, dbconfig.PostgresConnectString)
if err != nil {
break
}
err = initMySQLDB(false)
if err != nil {
break
}
err = initMySQLDB(true)
if err != nil {
break
}
err = initSQLiteDB()
2022-05-05 13:01:42 +02:00
default:
panic("invalid testsuite flag. Test suite name (postgres, mysql, mariadb, cockroach, sqlite or all)")
}
2023-07-21 13:20:44 +02:00
if err != nil {
fmt.Println(errfmt.Trace(err))
os.Exit(1)
2023-07-21 13:20:44 +02:00
}
}
2023-07-21 13:20:44 +02:00
func initSQLiteDB() error {
err := sqlite.GenerateDSN(dbconfig.SakilaDBPath, repo.GetTestsFilePath("./.gentestdata/sqlite/sakila"))
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to generate sqlite sakila database types: %w", err)
}
err = sqlite.GenerateDSN(dbconfig.ChinookDBPath, repo.GetTestsFilePath("./.gentestdata/sqlite/chinook"))
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to generate sqlite chinook database types: %w", err)
}
err = sqlite.GenerateDSN(dbconfig.TestSampleDBPath, repo.GetTestsFilePath("./.gentestdata/sqlite/test_sample"))
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to generate sqlite test_sample database types: %w", err)
}
return nil
2019-07-29 18:08:53 +02:00
}
2023-07-21 13:20:44 +02:00
func initMySQLDB(isMariaDB bool) error {
2019-07-29 18:08:53 +02:00
mySQLDBs := []string{
2019-08-01 16:56:54 +02:00
"dvds",
"dvds2",
2019-07-29 18:08:53 +02:00
"test_sample",
}
for _, dbName := range mySQLDBs {
2021-12-18 13:55:40 +01:00
host := dbconfig.MySqLHost
port := dbconfig.MySQLPort
user := dbconfig.MySQLUser
pass := dbconfig.MySQLPassword
if isMariaDB {
host = dbconfig.MariaDBHost
port = dbconfig.MariaDBPort
user = dbconfig.MariaDBUser
pass = dbconfig.MariaDBPassword
}
cmdLine := fmt.Sprintf("mysql -h %s -P %d -u %s -p%s %s < %s", host, port, user, pass, dbName,
"./testdata/init/mysql/"+dbName+".sql")
2019-08-08 12:02:32 +02:00
fmt.Println(cmdLine)
cmd := exec.Command("sh", "-c", cmdLine) // #nosec G204
2019-07-29 18:08:53 +02:00
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err := cmd.Run()
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to initialize mysql database %s: %w", dbName, err)
}
2019-07-29 18:08:53 +02:00
err = mysql.Generate("./.gentestdata/mysql", mysql.DBConnection{
2021-12-18 13:55:40 +01:00
Host: host,
Port: port,
User: user,
Password: pass,
2019-08-19 10:40:34 +02:00
DBName: dbName,
2019-07-29 18:08:53 +02:00
})
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to generate jet types for '%s' database: %w", dbName, err)
}
2019-07-29 18:08:53 +02:00
}
2023-07-21 13:20:44 +02:00
return nil
2019-07-29 18:08:53 +02:00
}
2023-07-21 13:20:44 +02:00
func initPostgresDB(dbType string, connectionString string) error {
2022-05-05 13:01:42 +02:00
db, err := sql.Open("postgres", connectionString)
2019-06-11 12:47:35 +02:00
if err != nil {
2023-07-21 13:20:44 +02:00
return fmt.Errorf("failed to open '%s' db connection '%s': %w", dbType, connectionString, err)
2019-06-11 12:47:35 +02:00
}
2023-07-21 13:20:44 +02:00
defer db.Close()
2019-06-21 13:56:57 +02:00
schemaNames := []string{
2022-05-05 13:01:42 +02:00
"northwind",
2019-06-21 13:56:57 +02:00
"dvds",
"test_sample",
"chinook",
"chinook2",
2019-06-21 13:56:57 +02:00
}
2019-06-11 12:47:35 +02:00
2019-06-21 13:56:57 +02:00
for _, schemaName := range schemaNames {
2022-05-05 13:01:42 +02:00
fmt.Println("\nInitializing", schemaName, "schema...")
2019-06-11 12:47:35 +02:00
// retry add due to a concurrency issue in CockroachDB, specifically a TransactionRetryError
err = retry(3, func() error {
return execFile(db, fmt.Sprintf("./testdata/init/%s/%s.sql", dbType, schemaName))
})
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to execute sql file: %w", err)
}
2019-07-17 11:03:16 +02:00
2022-05-05 13:01:42 +02:00
err = postgres.GenerateDSN(connectionString, schemaName, "./.gentestdata")
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to generate jet types: %w", err)
}
2019-06-21 13:56:57 +02:00
}
2023-07-21 13:20:44 +02:00
return nil
2019-06-11 12:47:35 +02:00
}
func retry(count int, f func() error) error {
for i := 0; i < count; i++ {
err := f()
if err == nil {
break
}
if i == count-1 {
return err
}
}
return nil
}
2023-07-21 13:20:44 +02:00
func execFile(db *sql.DB, sqlFilePath string) error {
testSampleSql, err := os.ReadFile(sqlFilePath) // #nosec G304
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to read sql file - %s: %w", sqlFilePath, err)
}
2019-07-29 18:08:53 +02:00
2022-05-05 13:01:42 +02:00
err = execInTx(db, func(tx *sql.Tx) error {
_, err := tx.Exec(string(testSampleSql))
return err
})
2023-07-21 13:20:44 +02:00
if err != nil {
return fmt.Errorf("failed to execute sql file - %s: %w", sqlFilePath, err)
}
return nil
2019-06-11 12:47:35 +02:00
}
2019-06-21 13:56:57 +02:00
2022-05-05 13:01:42 +02:00
func execInTx(db *sql.DB, f func(tx *sql.Tx) error) error {
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{
Isolation: sql.LevelReadUncommitted, // to speed up initialization of test database
})
if err != nil {
2023-07-21 13:20:44 +02:00
return fmt.Errorf("failed to start transaction: %w", err)
2022-05-05 13:01:42 +02:00
}
err = f(tx)
if err != nil {
rollBackError := tx.Rollback()
if rollBackError != nil {
return errors.Join(rollBackError, err)
}
2022-05-05 13:01:42 +02:00
return err
}
2023-07-21 13:20:44 +02:00
err = tx.Commit()
2019-06-21 13:56:57 +02:00
if err != nil {
2023-07-21 13:20:44 +02:00
return fmt.Errorf("failed to commit transaction")
2019-06-21 13:56:57 +02:00
}
2023-07-21 13:20:44 +02:00
return nil
2019-06-21 13:56:57 +02:00
}