Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ linters:
- testifylint
- unconvert
- unparam
- wastedassign
- whitespace
settings:
depguard:
Expand All @@ -50,7 +51,6 @@ linters:
gocritic:
disabled-checks:
- regexpMust
- appendAssign
- exitAfterDefer
- ifElseChain
- deprecatedComment
Expand Down Expand Up @@ -270,6 +270,7 @@ linters:
- error-nil
- expected-actual
- formatter
- go-require
- len
- negative-positive
- require-error
Expand All @@ -279,7 +280,6 @@ linters:
- useless-assert
disable:
- float-compare
- go-require
exclusions:
generated: lax
presets:
Expand All @@ -290,9 +290,6 @@ linters:
- linters:
- errcheck
path: (pkg/mock/.*\.go)
- linters:
- errcheck
path: (pd-analysis|pd-api-bench|pd-backup|pd-ctl|pd-heartbeat-bench|pd-recover|pd-simulator|pd-tso-bench|pd-ut|regions-dump|stores-dump)
- linters:
- recvcheck
path: pkg/response/region.go
Expand Down
2 changes: 1 addition & 1 deletion pkg/mcs/tso/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func (s *Server) startServer() (err error) {
func CreateServer(ctx context.Context, cfg *Config) *Server {
addr := cfg.GetAdvertiseListenAddr()
parsed, err := url.Parse(addr)
advertiseListenHost := ""
var advertiseListenHost string
if err != nil {
if _, _, splitErr := net.SplitHostPort(addr); splitErr != nil {
panic(fmt.Sprintf("invalid advertise listen address: %s", addr))
Expand Down
7 changes: 4 additions & 3 deletions pkg/schedule/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package config
import (
"encoding/json"
"math"
"slices"
"time"

"github.com/pingcap/errors"
Expand Down Expand Up @@ -171,7 +172,7 @@ func adjustSchedulers(v *SchedulerConfigs, defValue SchedulerConfigs) {
// Make a copy to avoid changing DefaultSchedulers unexpectedly.
// When reloading from storage, the config is passed to json.Unmarshal.
// Without clone, the DefaultSchedulers could be overwritten.
*v = append(defValue[:0:0], defValue...)
*v = slices.Clone(defValue)
}
}

Expand Down Expand Up @@ -343,7 +344,7 @@ type ScheduleConfig struct {

// Clone returns a cloned scheduling configuration.
func (c *ScheduleConfig) Clone() *ScheduleConfig {
schedulers := append(c.Schedulers[:0:0], c.Schedulers...)
schedulers := slices.Clone(c.Schedulers)
var storeLimit map[uint64]StoreLimitConfig
if c.StoreLimit != nil {
storeLimit = make(map[uint64]StoreLimitConfig, len(c.StoreLimit))
Expand Down Expand Up @@ -760,7 +761,7 @@ type ReplicationConfig struct {

// Clone makes a deep copy of the config.
func (c *ReplicationConfig) Clone() *ReplicationConfig {
locationLabels := append(c.LocationLabels[:0:0], c.LocationLabels...)
locationLabels := slices.Clone(c.LocationLabels)
cfg := *c
cfg.LocationLabels = locationLabels
return &cfg
Expand Down
19 changes: 14 additions & 5 deletions pkg/schedule/schedulers/balance_region_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"time"

"github.com/docker/go-units"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/pingcap/kvproto/pkg/metapb"
Expand Down Expand Up @@ -857,29 +858,37 @@ func TestBalanceRegionEmptyRegion(t *testing.T) {
}

func TestConcurrencyUpdateConfig(t *testing.T) {
as := assert.New(t)
re := require.New(t)
cancel, _, tc, oc := prepareSchedulersTest()
defer cancel()
hb, err := CreateScheduler(types.ScatterRangeScheduler, oc, storage.NewStorageWithMemoryBackend(), ConfigSliceDecoder(types.ScatterRangeScheduler, []string{"s_00", "s_50", "t"}))
sche := hb.(*scatterRangeScheduler)
re.NoError(err)
ch := make(chan struct{})
stopCh := make(chan struct{})
workerDone := make(chan struct{})
args := []string{"test", "s_00", "s_99"}
go func() {
defer close(workerDone)
for {
select {
case <-ch:
case <-stopCh:
return
default:
}
re.NoError(sche.config.buildWithArgs(args))
re.NoError(sche.config.persist())
if !as.NoError(sche.config.buildWithArgs(args)) {
return
}
if !as.NoError(sche.config.persist()) {
return
}
}
}()
for range 1000 {
sche.Schedule(tc, false)
}
ch <- struct{}{}
close(stopCh)
<-workerDone
}

func TestBalanceWhenRegionNotHeartbeat(t *testing.T) {
Expand Down
7 changes: 4 additions & 3 deletions pkg/schedule/schedulers/hot_region_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"io"
"net/http"
"slices"
"time"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -571,9 +572,9 @@ type prioritiesConfig struct {
}

func (conf *hotRegionSchedulerConfig) applyPrioritiesConfig(p prioritiesConfig) {
conf.ReadPriorities = append(p.read[:0:0], p.read...)
conf.WriteLeaderPriorities = append(p.writeLeader[:0:0], p.writeLeader...)
conf.WritePeerPriorities = append(p.writePeer[:0:0], p.writePeer...)
conf.ReadPriorities = slices.Clone(p.read)
conf.WriteLeaderPriorities = slices.Clone(p.writeLeader)
conf.WritePeerPriorities = slices.Clone(p.writePeer)
}

func getReadPriorities(c *prioritiesConfig) []string {
Expand Down
15 changes: 12 additions & 3 deletions pkg/utils/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,22 @@ func NewRequestHeader(clusterID uint64) *pdpb.RequestHeader {
}
}

// MustNewGrpcClient must create a new PD grpc client.
func MustNewGrpcClient(re *require.Assertions, addr string) (pdpb.PDClient, *grpc.ClientConn) {
// NewGrpcClient creates a new PD grpc client.
func NewGrpcClient(addr string) (pdpb.PDClient, *grpc.ClientConn, error) {
// TODO: use grpc.NewClient instead of grpc.Dial.
//nolint:staticcheck
conn, err := grpc.Dial(strings.TrimPrefix(addr, "http://"), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, nil, err
}
return pdpb.NewPDClient(conn), conn, nil
}

// MustNewGrpcClient must create a new PD grpc client.
func MustNewGrpcClient(re *require.Assertions, addr string) (pdpb.PDClient, *grpc.ClientConn) {
client, conn, err := NewGrpcClient(addr)
re.NoError(err)
return pdpb.NewPDClient(conn), conn
return client, conn
}

// CleanServer is used to clean data directory.
Expand Down
5 changes: 3 additions & 2 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"net/url"
"os"
"path/filepath"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -594,7 +595,7 @@ func migrateConfigurationFromFile(meta *configutil.ConfigMetaData) error {

// Clone returns a cloned PD server config.
func (c *PDServerConfig) Clone() *PDServerConfig {
runtimeServices := append(c.RuntimeServices[:0:0], c.RuntimeServices...)
runtimeServices := slices.Clone(c.RuntimeServices)
cfg := *c
cfg.RuntimeServices = runtimeServices
return &cfg
Expand Down Expand Up @@ -954,7 +955,7 @@ func AdjustMetaServiceGroups(metaGroups map[string]string) error {
// Clone makes a deep copy of the keyspace config.
func (c *KeyspaceConfig) Clone() *KeyspaceConfig {
cfg := *c
cfg.PreAlloc = append(c.PreAlloc[:0:0], c.PreAlloc...)
cfg.PreAlloc = slices.Clone(c.PreAlloc)
if c.MetaServiceGroups != nil {
cfg.MetaServiceGroups = make(map[string]string, len(c.MetaServiceGroups))
for name, endpoint := range c.MetaServiceGroups {
Expand Down
22 changes: 14 additions & 8 deletions tests/integrations/client/global_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"testing"
"time"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
"google.golang.org/grpc"
Expand All @@ -41,15 +41,15 @@ import (
const globalConfigPath = "/global/config/"

type testReceiver struct {
re *require.Assertions
as *assert.Assertions
ctx context.Context
grpc.ServerStream
}

func (s testReceiver) Send(m *pdpb.WatchGlobalConfigResponse) error {
log.Info("received", zap.Any("received", m.GetChanges()))
for _, change := range m.GetChanges() {
s.re.Contains(change.Name, globalConfigPath+string(change.Payload))
s.as.Contains(change.Name, globalConfigPath+string(change.Payload))
}
return nil
}
Expand Down Expand Up @@ -174,7 +174,7 @@ func (suite *globalConfigTestSuite) TestRejectInvalidConfigPath() {

err = suite.server.WatchGlobalConfig(&pdpb.WatchGlobalConfigRequest{
ConfigPath: configPath,
}, testReceiver{re: re, ctx: suite.server.Context()})
}, testReceiver{as: assert.New(suite.T()), ctx: suite.server.Context()})
re.Equal(codes.InvalidArgument, status.Code(err), configPath)
}
}
Expand Down Expand Up @@ -265,7 +265,7 @@ func (suite *globalConfigTestSuite) TestResourceGroupControllerPrefixLoadCompati

err = suite.server.WatchGlobalConfig(&pdpb.WatchGlobalConfigRequest{
ConfigPath: controllerPath,
}, testReceiver{re: re, ctx: suite.server.Context()})
}, testReceiver{as: assert.New(suite.T()), ctx: suite.server.Context()})
re.Equal(codes.InvalidArgument, status.Code(err))
}

Expand Down Expand Up @@ -455,14 +455,20 @@ func (suite *globalConfigTestSuite) TestWatch() {
}
}()
ctx, cancel := context.WithCancel(suite.server.Context())
defer cancel()
server := testReceiver{re: suite.Require(), ctx: ctx}
as := assert.New(suite.T())
server := testReceiver{as: as, ctx: ctx}
watchDone := make(chan struct{})
go func() {
defer close(watchDone)
err := suite.server.WatchGlobalConfig(&pdpb.WatchGlobalConfigRequest{
ConfigPath: globalConfigPath,
Revision: 0,
}, server)
re.NoError(err)
as.NoError(err)
}()
defer func() {
cancel()
<-watchDone
}()
for i := range 6 {
_, err := suite.server.GetClient().Put(suite.server.Context(), getEtcdPath(strconv.Itoa(i)), strconv.Itoa(i))
Expand Down
22 changes: 17 additions & 5 deletions tests/server/api/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sync"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

Expand Down Expand Up @@ -1179,6 +1180,7 @@ func (suite *ruleTestSuite) checkConcurrency(cluster *tests.TestCluster) {
func (suite *ruleTestSuite) checkConcurrencyWith(cluster *tests.TestCluster,
genBundle func(int) []placement.GroupBundle,
checkBundle func([]placement.GroupBundle, int) bool) {
as := assert.New(suite.T())
re := suite.Require()
leaderServer := cluster.GetLeaderServer()
pdAddr := leaderServer.GetAddr()
Expand All @@ -1187,21 +1189,31 @@ func (suite *ruleTestSuite) checkConcurrencyWith(cluster *tests.TestCluster,
syncutil.RWMutex
val int
}{}
wg := sync.WaitGroup{}
wg := &sync.WaitGroup{}

for i := 1; i <= 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
bundle := genBundle(i)
data, err := json.Marshal(bundle)
re.NoError(err)
if !as.NoError(err) {
return
}
for range 10 {
expectResult.Lock()
err = testutil.CheckPostJSON(tests.TestDialClient, urlPrefix+"/config/placement-rule", data, testutil.StatusOK(re))
re.NoError(err)
expectResult.val = i
statusOK := false
err = testutil.CheckPostJSON(tests.TestDialClient, urlPrefix+"/config/placement-rule", data,
func(resp []byte, statusCode int, _ http.Header) {
statusOK = as.Equal(http.StatusOK, statusCode, "resp: "+string(resp))
})
if err == nil && statusOK {
expectResult.val = i
}
expectResult.Unlock()
if !as.NoError(err) || !statusOK {
return
}
}
}(i)
}
Expand Down
47 changes: 19 additions & 28 deletions tests/server/apiv2/handlers/keyspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,46 +198,37 @@ func (suite *keyspaceTestSuite) TestUpdateKeyspaceConfigPreconditionsConcurrentS

nextKey := "next_file_id"
start := make(chan struct{})
results := make(chan int, 2)
type updateResult struct {
status int
body string
err error
}
results := make(chan updateResult, 2)

go func() {
<-start
next := "1000"
status, body, _ := tryUpdateKeyspaceConfig(re, suite.server, created.Name, &handlers.UpdateConfigParams{
Config: map[string]*string{
nextKey: &next,
},
Preconditions: map[string]*string{
nextKey: nil,
},
})
if status != http.StatusOK && status != http.StatusConflict {
re.FailNow("unexpected status", "status=%d body=%s", status, body)
}
results <- status
}()
go func() {
update := func(next string) {
<-start
next := "2000"
status, body, _ := tryUpdateKeyspaceConfig(re, suite.server, created.Name, &handlers.UpdateConfigParams{
status, body, _, err := updateKeyspaceConfig(suite.server, created.Name, &handlers.UpdateConfigParams{
Config: map[string]*string{
nextKey: &next,
},
Preconditions: map[string]*string{
nextKey: nil,
},
})
if status != http.StatusOK && status != http.StatusConflict {
re.FailNow("unexpected status", "status=%d body=%s", status, body)
}
results <- status
}()
results <- updateResult{status: status, body: body, err: err}
}
go update("1000")
go update("2000")

close(start)

s1 := <-results
s2 := <-results
re.ElementsMatch([]int{http.StatusOK, http.StatusConflict}, []int{s1, s2})
r1 := <-results
r2 := <-results
re.NoError(r1.err)
re.NoError(r2.err)
re.Contains([]int{http.StatusOK, http.StatusConflict}, r1.status, r1.body)
re.Contains([]int{http.StatusOK, http.StatusConflict}, r2.status, r2.body)
re.ElementsMatch([]int{http.StatusOK, http.StatusConflict}, []int{r1.status, r2.status})
}

func (suite *keyspaceTestSuite) TestUpdateKeyspaceState() {
Expand Down
Loading
Loading