180 lines
4.1 KiB
Smarty
180 lines
4.1 KiB
Smarty
type mysqlTester struct {
|
|
dbConn *sql.DB
|
|
|
|
dbName string
|
|
host string
|
|
user string
|
|
pass string
|
|
sslmode string
|
|
port int
|
|
|
|
optionFile string
|
|
|
|
testDBName string
|
|
}
|
|
|
|
func init() {
|
|
dbMain = &mysqlTester{}
|
|
}
|
|
|
|
func (m *mysqlTester) setup() error {
|
|
var err error
|
|
|
|
m.dbName = viper.GetString("mysql.dbname")
|
|
m.host = viper.GetString("mysql.host")
|
|
m.user = viper.GetString("mysql.user")
|
|
m.pass = viper.GetString("mysql.pass")
|
|
m.port = viper.GetInt("mysql.port")
|
|
m.sslmode = viper.GetString("mysql.sslmode")
|
|
// Create a randomized db name.
|
|
m.testDBName = randomize.StableDBName(m.dbName)
|
|
|
|
if err = m.makeOptionFile(); err != nil {
|
|
return errors.Prefix("couldn't make option file", err)
|
|
}
|
|
|
|
if err = m.dropTestDB(); err != nil {
|
|
return errors.Err(err)
|
|
}
|
|
if err = m.createTestDB(); err != nil {
|
|
return errors.Err(err)
|
|
}
|
|
|
|
dumpCmd := exec.Command("mysqldump", m.defaultsFile(), "--no-data", m.dbName)
|
|
createCmd := exec.Command("mysql", m.defaultsFile(), "--database", m.testDBName)
|
|
|
|
r, w := io.Pipe()
|
|
dumpCmd.Stdout = w
|
|
createCmd.Stdin = newFKeyDestroyer(rgxMySQLkey, r)
|
|
|
|
if err = dumpCmd.Start(); err != nil {
|
|
return errors.Prefix("failed to start mysqldump command", err)
|
|
}
|
|
if err = createCmd.Start(); err != nil {
|
|
return errors.Prefix("failed to start mysql command", err)
|
|
}
|
|
|
|
if err = dumpCmd.Wait(); err != nil {
|
|
fmt.Println(err)
|
|
return errors.Prefix("failed to wait for mysqldump command", err)
|
|
}
|
|
|
|
w.Close() // After dumpCmd is done, close the write end of the pipe
|
|
|
|
if err = createCmd.Wait(); err != nil {
|
|
fmt.Println(err)
|
|
return errors.Prefix("failed to wait for mysql command", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *mysqlTester) sslMode(mode string) string {
|
|
switch mode {
|
|
case "true":
|
|
return "REQUIRED"
|
|
case "false":
|
|
return "DISABLED"
|
|
default:
|
|
return "PREFERRED"
|
|
}
|
|
}
|
|
|
|
func (m *mysqlTester) defaultsFile() string {
|
|
return fmt.Sprintf("--defaults-file=%s", m.optionFile)
|
|
}
|
|
|
|
func (m *mysqlTester) makeOptionFile() error {
|
|
tmp, err := ioutil.TempFile("", "optionfile")
|
|
if err != nil {
|
|
return errors.Prefix("failed to create option file", err)
|
|
}
|
|
|
|
isTCP := false
|
|
_, err = os.Stat(m.host)
|
|
if os.IsNotExist(err) {
|
|
isTCP = true
|
|
} else if err != nil {
|
|
return errors.Prefix("could not stat m.host", err)
|
|
}
|
|
|
|
fmt.Fprintln(tmp, "[client]")
|
|
fmt.Fprintf(tmp, "host=%s\n", m.host)
|
|
fmt.Fprintf(tmp, "port=%d\n", m.port)
|
|
fmt.Fprintf(tmp, "user=%s\n", m.user)
|
|
fmt.Fprintf(tmp, "password=%s\n", m.pass)
|
|
fmt.Fprintf(tmp, "ssl-mode=%s\n", m.sslMode(m.sslmode))
|
|
if isTCP {
|
|
fmt.Fprintln(tmp, "protocol=tcp")
|
|
}
|
|
|
|
fmt.Fprintln(tmp, "[mysqldump]")
|
|
fmt.Fprintf(tmp, "host=%s\n", m.host)
|
|
fmt.Fprintf(tmp, "port=%d\n", m.port)
|
|
fmt.Fprintf(tmp, "user=%s\n", m.user)
|
|
fmt.Fprintf(tmp, "password=%s\n", m.pass)
|
|
fmt.Fprintf(tmp, "ssl-mode=%s\n", m.sslMode(m.sslmode))
|
|
if isTCP {
|
|
fmt.Fprintln(tmp, "protocol=tcp")
|
|
}
|
|
|
|
m.optionFile = tmp.Name()
|
|
|
|
return tmp.Close()
|
|
}
|
|
|
|
func (m *mysqlTester) createTestDB() error {
|
|
sql := fmt.Sprintf("create database %s;", m.testDBName)
|
|
return m.runCmd(sql, "mysql")
|
|
}
|
|
|
|
func (m *mysqlTester) dropTestDB() error {
|
|
sql := fmt.Sprintf("drop database if exists %s;", m.testDBName)
|
|
return m.runCmd(sql, "mysql")
|
|
}
|
|
|
|
func (m *mysqlTester) teardown() error {
|
|
if m.dbConn != nil {
|
|
m.dbConn.Close()
|
|
}
|
|
|
|
if err := m.dropTestDB(); err != nil {
|
|
return errors.Err(err)
|
|
}
|
|
|
|
return os.Remove(m.optionFile)
|
|
}
|
|
|
|
func (m *mysqlTester) runCmd(stdin, command string, args ...string) error {
|
|
args = append([]string{m.defaultsFile()}, args...)
|
|
|
|
cmd := exec.Command(command, args...)
|
|
cmd.Stdin = strings.NewReader(stdin)
|
|
|
|
stdout := &bytes.Buffer{}
|
|
stderr := &bytes.Buffer{}
|
|
cmd.Stdout = stdout
|
|
cmd.Stderr = stderr
|
|
if err := cmd.Run(); err != nil {
|
|
fmt.Println("failed running:", command, args)
|
|
fmt.Println(stdout.String())
|
|
fmt.Println(stderr.String())
|
|
return errors.Err(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *mysqlTester) conn() (*sql.DB, error) {
|
|
if m.dbConn != nil {
|
|
return m.dbConn, nil
|
|
}
|
|
|
|
var err error
|
|
m.dbConn, err = sql.Open("mysql", drivers.MySQLBuildQueryString(m.user, m.pass, m.testDBName, m.host, m.port, m.sslmode))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return m.dbConn, nil
|
|
}
|