Skip to content

Commit

Permalink
Added type wire tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Hydrocharged committed Jun 12, 2022
1 parent aa21cd8 commit de8461d
Show file tree
Hide file tree
Showing 8 changed files with 904 additions and 33 deletions.
110 changes: 110 additions & 0 deletions enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package enginetest
import (
"context"
"fmt"
"io"
"net"
"strings"
"testing"
Expand Down Expand Up @@ -5392,6 +5393,115 @@ func TestPrepared(t *testing.T, harness Harness) {
}
}

func TestTypesOverWire(t *testing.T, h Harness, sessionBuilder server.SessionBuilder) {
harness, ok := h.(ClientHarness)
if !ok {
t.Skip("Cannot run TestTypesOverWire as the harness must implement ClientHarness")
}
harness.Setup(setup.MydbData)

port := getEmptyPort(t)
for _, script := range queries.TypeWireTests {
t.Run(script.Name, func(t *testing.T) {
ctx := NewContextWithClient(harness, sql.Client{
User: "root",
Address: "localhost",
})
serverConfig := server.Config{
Protocol: "tcp",
Address: fmt.Sprintf("localhost:%d", port),
MaxConnections: 1000,
}

engine := mustNewEngine(t, harness)
defer engine.Close()
engine.Analyzer.Catalog.MySQLDb.AddRootAccount()
for _, statement := range script.SetUpScript {
if sh, ok := harness.(SkippingHarness); ok {
if sh.SkipQueryTest(statement) {
t.Skip()
}
}
RunQueryWithContext(t, engine, harness, ctx, statement)
}

s, err := server.NewServer(serverConfig, engine, sessionBuilder, nil)
require.NoError(t, err)
go func() {
err := s.Start()
require.NoError(t, err)
}()
defer func() {
require.NoError(t, s.Close())
}()

conn, err := dbr.Open("mysql", fmt.Sprintf("root:@tcp(localhost:%d)/", port), nil)
require.NoError(t, err)
_, err = conn.Exec("USE mydb;")
require.NoError(t, err)
for queryIdx, query := range script.Queries {
r, err := conn.Query(query)
if assert.NoError(t, err) {
sch, engineIter, err := engine.Query(ctx, query)
require.NoError(t, err)
expectedRowSet := script.Results[queryIdx]
expectedRowIdx := 0
var engineRow sql.Row
for engineRow, err = engineIter.Next(ctx); err == nil; engineRow, err = engineIter.Next(ctx) {
if !assert.True(t, r.Next()) {
break
}
expectedRow := expectedRowSet[expectedRowIdx]
expectedRowIdx++
connRow := make([]*string, len(engineRow))
interfaceRow := make([]any, len(connRow))
for i := range connRow {
interfaceRow[i] = &connRow[i]
}
err = r.Scan(interfaceRow...)
if !assert.NoError(t, err) {
break
}
expectedEngineRow := make([]*string, len(engineRow))
for i := range engineRow {
sqlVal, err := sch[i].Type.SQL(nil, engineRow[i])
if !assert.NoError(t, err) {
break
}
if !sqlVal.IsNull() {
str := sqlVal.ToString()
expectedEngineRow[i] = &str
}
}

for i := range expectedEngineRow {
expectedVal := expectedEngineRow[i]
connVal := connRow[i]
if !assert.Equal(t, expectedVal == nil, connVal == nil) {
continue
}
if expectedVal != nil {
assert.Equal(t, *expectedVal, *connVal)
if script.Name == "JSON" {
// Different integrators may return their JSON strings with different spacing, so we
// special case the test since the spacing is not significant
*connVal = strings.Replace(*connVal, `, `, `,`, -1)
*connVal = strings.Replace(*connVal, `: "`, `:"`, -1)
}
assert.Equal(t, expectedRow[i], *connVal)
}
}
}
assert.True(t, err == io.EOF)
assert.False(t, r.Next())
require.NoError(t, r.Close())
}
}
require.NoError(t, conn.Close())
})
}
}

type memoryPersister struct {
users []*mysql_db.User
roles []*mysql_db.RoleEdge
Expand Down
8 changes: 6 additions & 2 deletions enginetest/memory_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import (
"log"
"testing"

"github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup"

"github.com/dolthub/go-mysql-server/enginetest"
"github.com/dolthub/go-mysql-server/enginetest/queries"
"github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup"
"github.com/dolthub/go-mysql-server/memory"
"github.com/dolthub/go-mysql-server/server"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/analyzer"
"github.com/dolthub/go-mysql-server/sql/expression"
Expand Down Expand Up @@ -751,6 +751,10 @@ func TestKeylessUniqueIndex(t *testing.T) {
enginetest.TestKeylessUniqueIndex(t, enginetest.NewDefaultMemoryHarness())
}

func TestTypesOverWire(t *testing.T) {
enginetest.TestTypesOverWire(t, enginetest.NewDefaultMemoryHarness(), server.DefaultSessionBuilder)
}

func mergableIndexDriver(dbs []sql.Database) sql.IndexDriver {
return memory.NewIndexDriver("mydb", map[string][]sql.DriverIndex{
"mytable": {
Expand Down
4 changes: 4 additions & 0 deletions enginetest/mysqlshim/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func NewMySQLShim(user string, password string, host string, port int) (*MySQLSh
if err != nil {
return nil, err
}
err = conn.Ping()
if err != nil {
return nil, err
}
return &MySQLShim{conn, make(map[string]string)}, nil
}

Expand Down
8 changes: 4 additions & 4 deletions enginetest/mysqlshim/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ func newMySQLIter(rows *dsql.Rows) mysqlIter {
scanType = reflect.TypeOf("")
case reflect.TypeOf(dsql.NullBool{}):
scanType = reflect.TypeOf(true)
//case reflect.TypeOf(dsql.NullByte{}): // Not supported in go 1.15, need to upgrade to 1.17
// scanType = reflect.TypeOf(byte(0))
case reflect.TypeOf(dsql.NullByte{}):
scanType = reflect.TypeOf(byte(0))
case reflect.TypeOf(dsql.NullFloat64{}):
scanType = reflect.TypeOf(float64(0))
//case reflect.TypeOf(dsql.NullInt16{}): // Not supported in go 1.15, need to upgrade to 1.17
// scanType = reflect.TypeOf(int16(0))
case reflect.TypeOf(dsql.NullInt16{}):
scanType = reflect.TypeOf(int16(0))
case reflect.TypeOf(dsql.NullInt32{}):
scanType = reflect.TypeOf(int32(0))
case reflect.TypeOf(dsql.NullInt64{}):
Expand Down
48 changes: 35 additions & 13 deletions enginetest/mysqlshim/mysql_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package mysqlshim

import (
"context"
"fmt"
"strings"
"testing"
Expand All @@ -30,16 +31,36 @@ import (
type MySQLHarness struct {
shim *MySQLShim
skippedQueries map[string]struct{}
setupData []setup.SetupScript
session sql.Session
}

func (m *MySQLHarness) Setup(source ...[]setup.SetupScript) {
//TODO implement me
panic("implement me")
//TODO: refactor to remove enginetest cycle
var _ enginetest.Harness = (*MySQLHarness)(nil)
var _ enginetest.IndexHarness = (*MySQLHarness)(nil)
var _ enginetest.ForeignKeyHarness = (*MySQLHarness)(nil)
var _ enginetest.KeylessTableHarness = (*MySQLHarness)(nil)
var _ enginetest.ClientHarness = (*MySQLHarness)(nil)
var _ enginetest.SkippingHarness = (*MySQLHarness)(nil)

func (m *MySQLHarness) Setup(setupData ...[]setup.SetupScript) {
m.setupData = nil
for i := range setupData {
m.setupData = append(m.setupData, setupData[i]...)
}
return
}

func (m *MySQLHarness) NewEngine(t *testing.T) (*sqle.Engine, error) {
//TODO implement me
panic("implement me")
return enginetest.NewEngineWithProviderSetup(t, m, m.shim, m.setupData)
}

func (m *MySQLHarness) NewContextWithClient(client sql.Client) *sql.Context {
session := sql.NewBaseSessionWithClientServer("address", client, 1)
return sql.NewContext(
context.Background(),
sql.WithSession(session),
)
}

func (m *MySQLHarness) Cleanup() error {
Expand All @@ -58,19 +79,13 @@ type MySQLTable struct {
tableName string
}

var _ enginetest.Harness = (*MySQLHarness)(nil)
var _ enginetest.SkippingHarness = (*MySQLHarness)(nil)
var _ enginetest.IndexHarness = (*MySQLHarness)(nil)
var _ enginetest.ForeignKeyHarness = (*MySQLHarness)(nil)
var _ enginetest.KeylessTableHarness = (*MySQLHarness)(nil)

// NewMySQLHarness returns a new MySQLHarness.
func NewMySQLHarness(user string, password string, host string, port int) (*MySQLHarness, error) {
shim, err := NewMySQLShim(user, password, host, port)
if err != nil {
return nil, err
}
return &MySQLHarness{shim, make(map[string]struct{})}, nil
return &MySQLHarness{shim, make(map[string]struct{}), nil, nil}, nil
}

// Parallelism implements the interface Harness.
Expand Down Expand Up @@ -126,7 +141,14 @@ func (m *MySQLHarness) NewTable(db sql.Database, name string, schema sql.Primary

// NewContext implements the interface Harness.
func (m *MySQLHarness) NewContext() *sql.Context {
return sql.NewEmptyContext()
if m.session == nil {
m.session = enginetest.NewBaseSession()
}

return sql.NewContext(
context.Background(),
sql.WithSession(m.session),
)
}

// SkipQueryTest implements the interface SkippingHarness.
Expand Down
Loading

0 comments on commit de8461d

Please sign in to comment.