Files
tidb/br/pkg/utils/db_test.go
2025-05-07 13:36:55 +00:00

143 lines
5.1 KiB
Go

// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0.
package utils_test
import (
"context"
"strings"
"testing"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/br/pkg/utils"
"github.com/pingcap/tidb/pkg/meta/model"
"github.com/pingcap/tidb/pkg/parser/ast"
"github.com/pingcap/tidb/pkg/parser/mysql"
"github.com/pingcap/tidb/pkg/planner/core/resolve"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util/chunk"
"github.com/pingcap/tidb/pkg/util/sqlexec"
"github.com/stretchr/testify/require"
)
type mockRestrictedSQLExecutor struct {
rows []chunk.Row
fields []*resolve.ResultField
errHappen bool
}
func (m *mockRestrictedSQLExecutor) ParseWithParams(ctx context.Context, sql string, args ...any) (ast.StmtNode, error) {
return nil, nil
}
func (m *mockRestrictedSQLExecutor) ExecRestrictedStmt(ctx context.Context, stmt ast.StmtNode, opts ...sqlexec.OptionFuncAlias) ([]chunk.Row, []*resolve.ResultField, error) {
return nil, nil, nil
}
func (m *mockRestrictedSQLExecutor) ExecRestrictedSQL(ctx context.Context, opts []sqlexec.OptionFuncAlias, sql string, args ...any) ([]chunk.Row, []*resolve.ResultField, error) {
if m.errHappen {
return nil, nil, errors.New("injected error")
}
if strings.Contains(sql, "show config") {
return m.rows, m.fields, nil
} else if strings.Contains(sql, "set config") && strings.Contains(sql, "gc.ratio-threshold") {
value := args[0].(string)
for _, r := range m.rows {
d := types.Datum{}
d.SetString(value, "")
chunk.MutRow(r).SetDatum(3, d)
}
}
return nil, nil, nil
}
func TestCheckLogBackupTaskExist(t *testing.T) {
require.False(t, utils.CheckLogBackupTaskExist())
utils.LogBackupTaskCountInc()
require.True(t, utils.CheckLogBackupTaskExist())
utils.LogBackupTaskCountDec()
require.False(t, utils.CheckLogBackupTaskExist())
}
func TestGc(t *testing.T) {
// config format:
// MySQL [(none)]> show config where name = 'gc.ratio-threshold';
// +------+-------------------+--------------------+-------+
// | Type | Instance | Name | Value |
// +------+-------------------+--------------------+-------+
// | tikv | 172.16.6.46:3460 | gc.ratio-threshold | 1.1 |
// | tikv | 172.16.6.47:3460 | gc.ratio-threshold | 1.1 |
// +------+-------------------+--------------------+-------+
fields := make([]*resolve.ResultField, 4)
tps := []*types.FieldType{
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
}
for i := range tps {
rf := new(resolve.ResultField)
rf.Column = new(model.ColumnInfo)
rf.Column.FieldType = *tps[i]
fields[i] = rf
}
rows := make([]chunk.Row, 0, 2)
row := chunk.MutRowFromValues("tikv", " 127.0.0.1:20161", "log-backup.enable", "1.1").ToRow()
rows = append(rows, row)
row = chunk.MutRowFromValues("tikv", " 127.0.0.1:20162", "log-backup.enable", "1.1").ToRow()
rows = append(rows, row)
s := &mockRestrictedSQLExecutor{rows: rows, fields: fields}
ratio, err := utils.GetGcRatio(s)
require.Nil(t, err)
require.Equal(t, ratio, "1.1")
err = utils.SetGcRatio(s, "-1.0")
require.Nil(t, err)
ratio, err = utils.GetGcRatio(s)
require.Nil(t, err)
require.Equal(t, ratio, "-1.0")
}
func TestRegionSplitInfo(t *testing.T) {
// config format:
// MySQL [(none)]> show config where name = 'coprocessor.region-split-size';
// +------+-------------------+-------------------------------+-------+
// | Type | Instance | Name | Value |
// +------+-------------------+-------------------------------+-------+
// | tikv | 127.0.0.1:20161 | coprocessor.region-split-size | 10MB |
// +------+-------------------+-------------------------------+-------+
// MySQL [(none)]> show config where name = 'coprocessor.region-split-keys';
// +------+-------------------+-------------------------------+--------+
// | Type | Instance | Name | Value |
// +------+-------------------+-------------------------------+--------+
// | tikv | 127.0.0.1:20161 | coprocessor.region-split-keys | 100000 |
// +------+-------------------+-------------------------------+--------+
fields := make([]*resolve.ResultField, 4)
tps := []*types.FieldType{
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
types.NewFieldType(mysql.TypeString),
}
for i := range tps {
rf := new(resolve.ResultField)
rf.Column = new(model.ColumnInfo)
rf.Column.FieldType = *tps[i]
fields[i] = rf
}
rows := make([]chunk.Row, 0, 1)
row := chunk.MutRowFromValues("tikv", "127.0.0.1:20161", "coprocessor.region-split-size", "10MB").ToRow()
rows = append(rows, row)
s := &mockRestrictedSQLExecutor{rows: rows, fields: fields}
require.Equal(t, utils.GetSplitSize(s), uint64(10000000))
rows = make([]chunk.Row, 0, 1)
row = chunk.MutRowFromValues("tikv", "127.0.0.1:20161", "coprocessor.region-split-keys", "100000").ToRow()
rows = append(rows, row)
s = &mockRestrictedSQLExecutor{rows: rows, fields: fields}
require.Equal(t, utils.GetSplitKeys(s), int64(100000))
}