Get mysql tests running.

- Needs disabling of Foreign Key constraints + upsert deletion to have a
  chance of working.
This commit is contained in:
Aaron L 2016-09-11 23:49:47 -07:00
parent 37a05de380
commit 1b5cea823f
4 changed files with 157 additions and 18 deletions

View file

@ -243,24 +243,20 @@ var defaultTestMainImports = map[string]imports{
},
"mysql": {
standard: importList{
`"testing"`,
`"os"`,
`"os/exec"`,
`"flag"`,
`"fmt"`,
`"io/ioutil"`,
`"bytes"`,
`"database/sql"`,
`"path/filepath"`,
`"time"`,
`"math/rand"`,
`"fmt"`,
`"io"`,
`"io/ioutil"`,
`"os"`,
`"os/exec"`,
`"strings"`,
},
thirdParty: importList{
`"github.com/pkg/errors"`,
`"github.com/spf13/viper"`,
`"github.com/vattle/sqlboiler/boil"`,
`"github.com/vattle/sqlboiler/bdb/drivers"`,
`_ "github.com/go-mysql-driver/mysql"`,
`_ "github.com/go-sql-driver/mysql"`,
},
},
}

View file

@ -1,19 +1,157 @@
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{}
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 = getDBNameHash(m.dbName)
if err = m.makeOptionFile(); err != nil {
return errors.Wrap(err, "couldn't make option file")
}
if err = m.dropTestDB(); err != nil {
return err
}
if err = m.createTestDB(); err != nil {
return err
}
dumpCmd := exec.Command("mysqldump", m.defaultsFile(), m.dbName)
createCmd := exec.Command("mysql", m.defaultsFile(), "--database", m.testDBName)
r, w := io.Pipe()
dumpCmd.Stdout = w
createCmd.Stdin = io.TeeReader(r, os.Stdout)
if err = dumpCmd.Start(); err != nil {
return errors.Wrap(err, "failed to start mysqldump command")
}
if err = createCmd.Start(); err != nil {
return errors.Wrap(err, "failed to start mysql command")
}
if err = dumpCmd.Wait(); err != nil {
fmt.Println(err)
return errors.Wrap(err, "failed to wait for mysqldump command")
}
w.Close() // After dumpCmd is done, close the write end of the pipe
if err = createCmd.Wait(); err != nil {
fmt.Println(err)
return errors.Wrap(err, "failed to wait for mysql command")
}
return nil
}
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.Wrap(err, "failed to create option file")
}
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)
// BUG: SSL Mode for whatever reason is backwards in the mysql driver
// taking options like true or false, but here taking options like
// required/disabled. Until this gets sorted, ignore this.
//fmt.Fprintf("ssl-mode=%s\n", m.password)
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)
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 err := m.dropTestDB(); err != nil {
return err
}
if m.dbConn != nil {
m.dbConn.Close()
}
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 err
}
return nil
}
func (m *mysqlTester) conn() *sql.DB {
return m.dbConn
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
}

View file

@ -44,8 +44,8 @@ func (p *pgTester) teardown() error {
return p.dropTestDB()
}
func (p *pgTester) conn() *sql.DB {
return p.dbConn
func (p *pgTester) conn() (*sql.DB, error) {
return p.dbConn, nil
}
// dropTestDB switches its connection to the template1 database temporarily

View file

@ -6,7 +6,7 @@ var (
type tester interface {
setup() error
conn() *sql.DB
conn() (*sql.DB, error)
teardown() error
}
@ -41,8 +41,13 @@ func TestMain(m *testing.M) {
os.Exit(-4)
}
conn, err := dbMain.conn()
if err != nil {
fmt.Println("failed to get connection:", err)
}
var code int
boil.SetDB(dbMain.conn())
boil.SetDB(conn)
code = m.Run()
if err = dbMain.teardown(); err != nil {