From 62d227bb888de7e834436794b6b8ef3c855574d1 Mon Sep 17 00:00:00 2001 From: Leon Zhang Date: Wed, 26 Dec 2018 15:35:52 +0800 Subject: [PATCH] for test coverage --- CHANGES.md | 10 ++++++++++ cmd/soar/soar_test.go | 42 ++++++++++++++++++++++++++++++++++++++++- common/chardet_test.go | 6 ++++++ common/config_test.go | 15 +++++++++++++++ common/example_test.go | 6 ++++++ common/markdown_test.go | 24 ++++++++++++++++++++--- common/meta_test.go | 8 ++++++-- common/signal_test.go | 2 ++ doc/environment.md | 4 ++++ env/env.go | 2 +- 10 files changed, 112 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f3701e2..138246c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,16 @@ ## 2018-12 - DOING: english translation +- replace mysql database driver mymysql with go-sql-driver +- add new -report-type [ast-json, tiast-json] +- command line dsn args support '@', '/', ':' in password +- add new heuristic rule RES.009, "SELECT * FROM tbl WHERE col = col = 'abc'" +- add new heuristic rule RuleColumnNotAllowType COL.018 +- fix #58 sampling not deal with NULL able string +- fix #172 compatible with mysql 5.1, which explain has no Index_Comment column +- fix #163 column.Tp may be nil, which may raise panic +- fix #151 bit type not config as int, when two columns compare will give ARG.003 suggestion. +- ## 2018-11 diff --git a/cmd/soar/soar_test.go b/cmd/soar/soar_test.go index 46050fd..5136a2a 100644 --- a/cmd/soar/soar_test.go +++ b/cmd/soar/soar_test.go @@ -60,7 +60,7 @@ func Test_Main_More(_ *testing.T) { orgRerportType := common.Config.ReportType for _, typ := range []string{ "json", "html", "markdown", "fingerprint", "compress", "pretty", "rewrite", - "ast", "tiast", "ast-json", "tiast-json", "tokenize", + "ast", "tiast", "ast-json", "tiast-json", "tokenize", "lint", } { common.Config.ReportType = typ main() @@ -104,3 +104,43 @@ func Test_Main_reportTool(t *testing.T) { common.Config.ReportType = orgRerportType common.Log.Debug("Exiting function: %s", common.GetFunctionName()) } + +func Test_Main_helpTools(t *testing.T) { + common.Log.Debug("Entering function: %s", common.GetFunctionName()) + + orgConfig := common.CheckConfig + common.CheckConfig = true + helpTools() + common.CheckConfig = orgConfig + + orgConfig = common.PrintVersion + common.PrintVersion = true + helpTools() + common.PrintVersion = orgConfig + + orgConfig = common.PrintConfig + common.PrintConfig = true + helpTools() + common.PrintConfig = orgConfig + + orgConfig = common.Config.ListHeuristicRules + common.Config.ListHeuristicRules = true + helpTools() + common.Config.ListHeuristicRules = orgConfig + + orgConfig = common.Config.ListRewriteRules + common.Config.ListRewriteRules = true + helpTools() + common.Config.ListRewriteRules = orgConfig + + orgConfig = common.Config.ListTestSqls + common.Config.ListTestSqls = true + helpTools() + common.Config.ListTestSqls = orgConfig + + orgConfig = common.Config.ListReportTypes + common.Config.ListReportTypes = true + helpTools() + common.Config.ListReportTypes = orgConfig + common.Log.Debug("Exiting function: %s", common.GetFunctionName()) +} diff --git a/common/chardet_test.go b/common/chardet_test.go index 0d6e411..5143b5a 100644 --- a/common/chardet_test.go +++ b/common/chardet_test.go @@ -23,6 +23,7 @@ import ( ) func TestChardet(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) charsets := []string{ "GB-18030", "UTF-8", @@ -38,9 +39,11 @@ func TestChardet(t *testing.T) { t.Errorf("file: %s, Want: %s, Get: %s", fileName, c, name) } } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestRemoveBOM(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) fileName := DevPath + "/common/testdata/UTF-8.bom.sql" buf, err := ioutil.ReadFile(fileName) if err != nil { @@ -49,9 +52,11 @@ func TestRemoveBOM(t *testing.T) { GoldenDiff(func() { fmt.Println(RemoveBOM(buf)) }, t.Name(), update) + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestCheckCharsetByBOM(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) fileName := DevPath + "/common/testdata/UTF-8.bom.sql" buf, err := ioutil.ReadFile(fileName) if err != nil { @@ -61,4 +66,5 @@ func TestCheckCharsetByBOM(t *testing.T) { if CheckCharsetByBOM(buf) != "UTF-8" { t.Errorf("checkCharsetByBOM Want: UTF-8, Get: %s", CheckCharsetByBOM(buf)) } + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/config_test.go b/common/config_test.go index 291e94d..8d7f253 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -30,6 +30,9 @@ var update = flag.Bool("update", false, "update .golden files") func TestMain(m *testing.M) { // 初始化 init BaseDir = DevPath + err := ParseConfig("") + LogIfError(err, "init ParseConfig") + Log.Debug("mysql_test init") // 分割线 flag.Parse() @@ -40,20 +43,25 @@ func TestMain(m *testing.M) { } func TestParseConfig(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) err := ParseConfig("") if err != nil { t.Error("sqlparser.Parse Error:", err) } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestReadConfigFile(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) if Config == nil { Config = new(Configuration) } Config.readConfigFile(filepath.Join(DevPath, "etc/soar.yaml")) + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestParseDSN(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) var dsns = []string{ "", "user:password@hostname:3307/database", @@ -82,16 +90,20 @@ func TestParseDSN(t *testing.T) { if nil != err { t.Fatal(err) } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestListReportTypes(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) err := GoldenDiff(func() { ListReportTypes() }, t.Name(), update) if nil != err { t.Fatal(err) } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestArgConfig(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) testArgs1 := [][]string{ {"soar", "-config", "=", "soar.yaml"}, {"soar", "-print-config", "-config", "soar.yaml"}, @@ -115,9 +127,11 @@ func TestArgConfig(t *testing.T) { t.Errorf("should return soar.yaml, but got %s", configFile) } } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestPrintConfiguration(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) Config.readConfigFile(filepath.Join(DevPath, "etc/soar.yaml")) oldLogOutput := Config.LogOutput Config.LogOutput = "soar.log" @@ -128,4 +142,5 @@ func TestPrintConfiguration(t *testing.T) { t.Error(err) } Config.LogOutput = oldLogOutput + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/example_test.go b/common/example_test.go index a0d0877..ca4fd49 100644 --- a/common/example_test.go +++ b/common/example_test.go @@ -19,6 +19,7 @@ package common import "fmt" func ExampleFormatDSN() { + Log.Debug("Entering function: %s", GetFunctionName()) dsxExp := &Dsn{ Addr: "127.0.0.1:3306", Schema: "mysql", @@ -32,9 +33,11 @@ func ExampleFormatDSN() { fmt.Println(FormatDSN(dsxExp)) // Output: root:1t'sB1g3rt@127.0.0.1:3306/mysql?charset=utf8mb4 + Log.Debug("Exiting function: %s", GetFunctionName()) } func ExampleIsColsPart() { + Log.Debug("Entering function: %s", GetFunctionName()) // IsColsPart() 会 按照顺序 检查两个Column队列是否是包含(或相等)关系。 a := []*Column{{Name: "1"}, {Name: "2"}, {Name: "3"}} b := []*Column{{Name: "1"}, {Name: "2"}} @@ -47,9 +50,11 @@ func ExampleIsColsPart() { fmt.Println(ab, ac, ad) // Output: true false true + Log.Debug("Exiting function: %s", GetFunctionName()) } func ExampleSortedKey() { + Log.Debug("Entering function: %s", GetFunctionName()) ages := map[string]int{ "a": 1, "c": 3, @@ -60,4 +65,5 @@ func ExampleSortedKey() { fmt.Print(ages[name]) } // Output: 1234 + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/markdown_test.go b/common/markdown_test.go index 8788e0d..befc4fb 100644 --- a/common/markdown_test.go +++ b/common/markdown_test.go @@ -26,6 +26,7 @@ import ( ) func TestMarkdownEscape(_ *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) var strs = []string{ "a`bc", "abc", @@ -35,9 +36,11 @@ func TestMarkdownEscape(_ *testing.T) { for _, str := range strs { fmt.Println(MarkdownEscape(str)) } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestMarkdown2Html(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) md := filepath.Join("testdata", t.Name()+".md") buf, err := ioutil.ReadFile(md) if err != nil { @@ -60,16 +63,28 @@ func TestMarkdown2Html(t *testing.T) { t.Fatal(err) } io.Copy(html, gd) + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestScore(t *testing.T) { - score := Score(50) - if score != "★ ★ ☆ ☆ ☆ 50分" { - t.Error(score) + Log.Debug("Entering function: %s", GetFunctionName()) + scores := map[int]string{ + 50: "★ ★ ☆ ☆ ☆ 50分", + 100: "★ ★ ★ ★ ★ 100分", + -1: "☆ ☆ ☆ ☆ ☆ 0分", + 101: "★ ★ ★ ★ ★ 100分", } + for score, want := range scores { + get := Score(score) + if want != get { + t.Error(score, want, get) + } + } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestLoadExternalResource(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) buf := loadExternalResource("../doc/themes/github.css") if buf == "" { t.Error("loadExternalResource local error") @@ -78,13 +93,16 @@ func TestLoadExternalResource(t *testing.T) { if buf == "" { t.Error("loadExternalResource http error") } + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestMarkdownHTMLHeader(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) err := GoldenDiff(func() { MarkdownHTMLHeader() }, t.Name(), update) if err != nil { t.Error(err) } + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/meta_test.go b/common/meta_test.go index c6e8080..1b4ebc7 100644 --- a/common/meta_test.go +++ b/common/meta_test.go @@ -21,6 +21,7 @@ import ( ) func TestGetDataTypeLength(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) typeList := map[string][]int{ "varchar(20)": {20}, "int(2)": {2}, @@ -37,10 +38,11 @@ func TestGetDataTypeLength(t *testing.T) { } } } - + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestGetDataTypeBase(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) typeList := map[string]string{ "varchar(20)": "varchar", "int(2)": "int", @@ -52,10 +54,11 @@ func TestGetDataTypeBase(t *testing.T) { t.Errorf("Not match, want %s, got %s", typeList[typ], got) } } - + Log.Debug("Exiting function: %s", GetFunctionName()) } func TestGetDataBytes(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) cols50604 := map[*Column]int{ // numeric type {Name: "col000", DataType: "tinyint", Character: "utf8"}: 1, @@ -137,4 +140,5 @@ func TestGetDataBytes(t *testing.T) { t.Errorf("Version: 5.5.0, %s Not match, want %d, got %d", col.Name, bytes, got) } } + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/signal_test.go b/common/signal_test.go index 853a2fa..a396e99 100644 --- a/common/signal_test.go +++ b/common/signal_test.go @@ -22,7 +22,9 @@ import ( ) func TestHandleSignal(t *testing.T) { + Log.Debug("Entering function: %s", GetFunctionName()) HandleSignal(func() { fmt.Println("done") }) + Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/doc/environment.md b/doc/environment.md index ef43298..a6152a8 100644 --- a/doc/environment.md +++ b/doc/environment.md @@ -21,3 +21,7 @@ * 语法检查 * 模拟执行 * 索引建议/去重 + +## 注意 +* 测试环境 MySQL 版本必须高于或等于线上环境 +* 测试环境需要所有权限(建议通过[docker](https://hub.docker.com/_/mysql/)启动),线上环境至少需要只读权限 diff --git a/env/env.go b/env/env.go index d9db4d2..9a0cf1a 100644 --- a/env/env.go +++ b/env/env.go @@ -101,7 +101,7 @@ func BuildEnv() (*VirtualEnv, *database.Connector) { // 判断测试环境与remote环境版本是否一致 if vEnvVersion < rEnvVersion { - common.Log.Warning("TestDSN MySQL version older than OnlineDSN, TestDSN will not be used", vEnvVersion, rEnvVersion) + common.Log.Warning("TestDSN MySQL version older than OnlineDSN(%d), TestDSN(%d) will not be used", vEnvVersion, rEnvVersion) common.Config.TestDSN.Disable = true } -- GitLab