提交 08cf841e 编写于 作者: martianzhang's avatar martianzhang

cleanup-test-database add test case

上级 99d9b11d
......@@ -80,16 +80,17 @@ func main() {
// 环境初始化,连接检查线上环境+构建测试环境
vEnv, rEnv := env.BuildEnv()
//如果使用CleanTestDataBase命令,则清除前1小时的数据库
if common.Config.CleanTestDataBase {
vEnv.CleanTestDataBase()
}
// 如果使用到测试环境,在这里环境清理
if common.Config.DropTestTemporary {
defer vEnv.CleanUp()
}
// 使用CleanupTestDatabase命令手动清理残余的`optimizer_xxx`数据库
// 为了保护当前正在评审的SQL,只清除前1小时前的残余
if common.Config.CleanupTestDatabase {
vEnv.CleanupTestDatabase()
}
// 对指定的库表进行索引重复检查
if common.Config.ReportType == "duplicate-key-checker" {
dupKeySuggest := advisor.DuplicateKeyChecker(rEnv)
......
......@@ -43,6 +43,7 @@ type Configration struct {
TestDSN *dsn `yaml:"test-dsn"` // 测试环境数据库配置
AllowOnlineAsTest bool `yaml:"allow-online-as-test"` // 允许Online环境也可以当作Test环境
DropTestTemporary bool `yaml:"drop-test-temporary"` // 是否清理Test环境产生的临时库表
CleanupTestDatabase bool `yaml:"cleanup-test-database"` // 清理残余的测试数据库(程序异常退出或未开启drop-test-temporary) issue #48
OnlySyntaxCheck bool `yaml:"only-syntax-check"` // 只做语法检查不输出优化建议
SamplingStatisticTarget int `yaml:"sampling-statistic-target"` // 数据采样因子,对应postgres的default_statistics_target
Sampling bool `yaml:"sampling"` // 数据采样开关
......@@ -119,7 +120,6 @@ type Configration struct {
Verbose bool `yaml:"verbose"` // verbose模式,会多输出一些信息
DryRun bool `yaml:"dry-run"` // 是否在预演环境执行
MaxPrettySQLLength int `yaml:"max-pretty-sql-length"` // 超出该长度的SQL会转换成指纹输出
CleanTestDataBase bool `yaml:"clean-test-database"` // 清理数据库 issue #48
}
// getDefaultLogOutput get default log-output by runtime.GOOS
......@@ -146,6 +146,7 @@ var Config = &Configration{
},
AllowOnlineAsTest: false,
DropTestTemporary: true,
CleanupTestDatabase: false,
DryRun: true,
OnlySyntaxCheck: false,
SamplingStatisticTarget: 100,
......@@ -220,7 +221,6 @@ var Config = &Configration{
ListTestSqls: false,
ListReportTypes: false,
MaxPrettySQLLength: 1024,
CleanTestDataBase: false,
}
type dsn struct {
......@@ -480,6 +480,7 @@ func readCmdFlags() error {
testDSN := flag.String("test-dsn", FormatDSN(Config.TestDSN), "TestDSN, 测试环境数据库配置, username:password@ip:port/schema")
allowOnlineAsTest := flag.Bool("allow-online-as-test", Config.AllowOnlineAsTest, "AllowOnlineAsTest, 允许线上环境也可以当作测试环境")
dropTestTemporary := flag.Bool("drop-test-temporary", Config.DropTestTemporary, "DropTestTemporary, 是否清理测试环境产生的临时库表")
cleanupTestDatabase := flag.Bool("cleanup-test-database", Config.CleanupTestDatabase, "单次运行清理历史1小时前残余的测试库。")
onlySyntaxCheck := flag.Bool("only-syntax-check", Config.OnlySyntaxCheck, "OnlySyntaxCheck, 只做语法检查不输出优化建议")
profiling := flag.Bool("profiling", Config.Profiling, "Profiling, 开启数据采样的情况下在测试环境执行Profile")
trace := flag.Bool("trace", Config.Trace, "Trace, 开启数据采样的情况下在测试环境执行Trace")
......@@ -547,7 +548,6 @@ func readCmdFlags() error {
verbose := flag.Bool("verbose", Config.Verbose, "Verbose")
dryrun := flag.Bool("dry-run", Config.DryRun, "是否在预演环境执行")
maxPrettySQLLength := flag.Int("max-pretty-sql-length", Config.MaxPrettySQLLength, "MaxPrettySQLLength, 超出该长度的SQL会转换成指纹输出")
cleanTestDataBase := flag.Bool("clean-test-database", Config.CleanTestDataBase, "由于程序异常退出,导致临时数据库的存在,可用此命令删除。")
// 一个不存在log-level,用于更新usage。
// 因为vitess里面也用了flag,这些vitess的参数我们不需要关注
if !Config.Verbose && runtime.GOOS != "windows" {
......@@ -566,6 +566,7 @@ func readCmdFlags() error {
Config.TestDSN = parseDSN(*testDSN, Config.TestDSN)
Config.AllowOnlineAsTest = *allowOnlineAsTest
Config.DropTestTemporary = *dropTestTemporary
Config.CleanupTestDatabase = *cleanupTestDatabase
Config.OnlySyntaxCheck = *onlySyntaxCheck
Config.Profiling = *profiling
Config.Trace = *trace
......@@ -651,7 +652,6 @@ func readCmdFlags() error {
Config.DryRun = *dryrun
Config.MaxPrettySQLLength = *maxPrettySQLLength
Config.MaxVarcharLength = *maxVarcharLength
Config.CleanTestDataBase = *cleanTestDataBase
if *ver {
version()
......
......@@ -150,35 +150,42 @@ func (ve VirtualEnv) CleanUp() bool {
return true
}
// CleanTestDataBase 清除一小时前的环境
func (ve *VirtualEnv) CleanTestDataBase() {
common.Log.Debug("CleanTestDataBase ...")
// CleanupTestDatabase 清除一小时前的环境
func (ve *VirtualEnv) CleanupTestDatabase() {
common.Log.Debug("CleanupTestDatabase ...")
dbs, err := ve.Query("show databases like 'optimizer%'")
if err == nil {
for index, row := range dbs.Rows {
s := strings.Split(row.Str(index), "_")
for _, row := range dbs.Rows {
testDatabase := row.Str(0)
// test temporary database format `opimtizer_YYMMDDHHmmss_randomString(16)`
if len(testDatabase) != 39 {
common.Log.Debug("CleanupTestDatabase by pass %s", testDatabase)
continue
}
s := strings.Split(testDatabase, "_")
pastTime, err := time.Parse("060102150405", s[1])
if err != nil {
common.Log.Error("CleanTestDataBase compute pastTime Error: %s", err)
common.Log.Error("CleanupTestDatabase compute pastTime Error: %s", err)
}
nowTime, err := time.Parse("060102150405", time.Now().Format("060102150405"))
if err != nil {
common.Log.Error("CleanTestDataBase compute nowTime Error: %s", err)
common.Log.Error("CleanupTestDatabase compute nowTime Error: %s", err)
}
// TODO: 1 hour should be configable
subHour := nowTime.Sub(pastTime).Hours()
if subHour > 1 {
_, err := ve.Query("drop database %s", row.Str(index))
_, err := ve.Query("drop database %s", testDatabase)
if err != nil {
common.Log.Error("CleanTestDataBase failed Error: %s", err)
common.Log.Error("CleanupTestDatabase failed Error: %s", err)
}
common.Log.Debug("CleanTestDataBase, done")
common.Log.Debug("CleanupTestDatabase drop database %s", testDatabase)
} else {
common.Log.Debug("CleanupTestDatabase by pass database %s, less than %d hours", testDatabase, subHour)
}
}
} else {
common.Log.Error("CleanTestDataBase failed Error:%s", err)
common.Log.Error("CleanupTestDatabase failed Error:%s", err)
}
}
// BuildVirtualEnv rEnv为SQL源环境,DB使用的信息从接口获取
......
......@@ -113,9 +113,34 @@ func TestNewVirtualEnv(t *testing.T) {
}, t.Name(), update)
}
func TestCleanupTestDatabase(t *testing.T) {
vEnv, _ := BuildEnv()
vEnv.Query("drop database if exists optimizer_100000000000_xxxxxxxxxxxxxxxx")
_, err := vEnv.Query("create database optimizer_100000000000_xxxxxxxxxxxxxxxx")
if err != nil {
t.Error(err)
}
vEnv.CleanupTestDatabase()
_, err = vEnv.Query("drop database optimizer_100000000000_xxxxxxxxxxxxxxxx")
if err == nil {
t.Error("optimizer_100000000000_xxxxxxxxxxxxxxxx exist, should be droped")
}
vEnv.Query("drop database if exists optimizer_100000000000")
_, err = vEnv.Query("create database optimizer_100000000000")
if err != nil {
t.Error(err)
}
vEnv.CleanupTestDatabase()
_, err = vEnv.Query("drop database optimizer_100000000000")
if err != nil {
t.Error("optimizer_100000000000 not exist, should not be droped")
}
}
func TestGenTableColumns(t *testing.T) {
vEnv, rEnv := BuildEnv()
vEnv.CleanTestDataBase()
vEnv.CleanupTestDatabase()
defer vEnv.CleanUp()
pretty.Println(common.Config.TestDSN.Disable)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册