mysql_test.go 4.6 KB
Newer Older
martianzhang's avatar
martianzhang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright 2018 Xiaomi, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package database

import (
20
	"flag"
martianzhang's avatar
martianzhang 已提交
21
	"fmt"
22
	"os"
martianzhang's avatar
martianzhang 已提交
23 24 25
	"testing"

	"github.com/XiaoMi/soar/common"
26

martianzhang's avatar
martianzhang 已提交
27 28 29
	"github.com/kr/pretty"
)

30 31 32 33 34
var connTest *Connector
var update = flag.Bool("update", false, "update .golden files")

func init() {
	common.BaseDir = common.DevPath
martianzhang's avatar
martianzhang 已提交
35 36 37 38 39
	err := common.ParseConfig("")
	common.LogIfError(err, "init ParseConfig")
	common.Log.Debug("mysql_test init")
	connTest, err = NewConnector(common.Config.TestDSN)
	if err != nil {
40 41 42 43
		common.Log.Critical("Test env Error: %v", err)
		os.Exit(0)
	}

martianzhang's avatar
martianzhang 已提交
44 45 46
	if _, err := connTest.Version(); err != nil {
		common.Log.Critical("Test env Error: %v", err)
		os.Exit(0)
47 48 49
	}
}

martianzhang's avatar
martianzhang 已提交
50
func TestQuery(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
51
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
52 53 54 55 56 57 58 59 60 61 62 63 64
	res, err := connTest.Query("select 0")
	if err != nil {
		t.Error(err.Error())
	}
	for res.Rows.Next() {
		var val int
		err = res.Rows.Scan(&val)
		if err != nil {
			t.Error(err.Error())
		}
		if val != 0 {
			t.Error("should return 0")
		}
martianzhang's avatar
martianzhang 已提交
65
	}
martianzhang's avatar
martianzhang 已提交
66
	res.Rows.Close()
67
	// TODO: timeout test
martianzhang's avatar
martianzhang 已提交
68
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
69 70
}

71
func TestColumnCardinality(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
72
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
73 74 75
	orgDatabase := connTest.Database
	connTest.Database = "sakila"
	a := connTest.ColumnCardinality("actor", "first_name")
76 77
	if a > 1 || a <= 0 {
		t.Error("sakila.actor.first_name cardinality should in [0, 1], now it's", a)
78 79
	}
	connTest.Database = orgDatabase
martianzhang's avatar
martianzhang 已提交
80
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
81 82 83
}

func TestDangerousSQL(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
84
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98
	testCase := map[string]bool{
		"select * from tb;delete from tb;": true,
		"show database;":                   false,
		"select * from t;":                 false,
		"explain delete from t;":           false,
	}

	db := Connector{}
	for sql, want := range testCase {
		got := db.dangerousQuery(sql)
		if got != want {
			t.Errorf("SQL:%s got:%v want:%v", sql, got, want)
		}
	}
martianzhang's avatar
martianzhang 已提交
99
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
100 101 102
}

func TestWarningsAndQueryCost(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
103
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
104 105 106 107 108 109
	common.Config.ShowWarnings = true
	common.Config.ShowLastQueryCost = true
	res, err := connTest.Query("explain select * from sakila.film")
	if err != nil {
		t.Error("Query Error: ", err)
	} else {
110 111 112 113 114 115 116
		for res.Warning.Next() {
			var str string
			err = res.Warning.Scan(str)
			if err != nil {
				t.Error(err.Error())
			}
			pretty.Println(str)
martianzhang's avatar
martianzhang 已提交
117
		}
martianzhang's avatar
martianzhang 已提交
118
		res.Warning.Close()
119
		fmt.Println(res.QueryCost, err)
martianzhang's avatar
martianzhang 已提交
120
	}
martianzhang's avatar
martianzhang 已提交
121
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
122 123 124
}

func TestVersion(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
125
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
126 127 128 129 130
	version, err := connTest.Version()
	if err != nil {
		t.Error(err.Error())
	}
	fmt.Println(version)
martianzhang's avatar
martianzhang 已提交
131
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
132 133
}

martianzhang's avatar
martianzhang 已提交
134
func TestRemoveSQLComments(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
135
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
	SQLs := []string{
		`-- comment`,
		`--`,
		`# comment`,
		`/* multi-line
comment*/`,
		`--
-- comment`,
	}

	err := common.GoldenDiff(func() {
		for _, sql := range SQLs {
			fmt.Println(RemoveSQLComments(sql))
		}
	}, t.Name(), update)
	if err != nil {
		t.Error(err)
	}
martianzhang's avatar
martianzhang 已提交
154
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
martianzhang's avatar
martianzhang 已提交
155
}
156 157

func TestSingleIntValue(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
158
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
159 160 161 162 163 164 165
	val, err := connTest.SingleIntValue("read_only")
	if err != nil {
		t.Error(err)
	}
	if val < 0 {
		t.Error("SingleIntValue, return should large than zero")
	}
martianzhang's avatar
martianzhang 已提交
166
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
167 168 169
}

func TestIsView(t *testing.T) {
martianzhang's avatar
martianzhang 已提交
170
	common.Log.Debug("Entering function: %s", common.GetFunctionName())
171 172 173 174 175 176
	originalDatabase := connTest.Database
	connTest.Database = "sakila"
	if !connTest.IsView("actor_info") {
		t.Error("actor_info should be a VIEW")
	}
	connTest.Database = originalDatabase
martianzhang's avatar
martianzhang 已提交
177
	common.Log.Debug("Exiting function: %s", common.GetFunctionName())
178
}