Skip to content

Commit

Permalink
Showing 5 changed files with 1,162 additions and 7 deletions.
1,039 changes: 1,039 additions & 0 deletions junitfile

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions pkg/schedule/schedulers/evict_leader.go
Original file line number Diff line number Diff line change
@@ -75,6 +75,9 @@ func (conf *evictLeaderSchedulerConfig) getStores() []uint64 {
}

func (conf *evictLeaderSchedulerConfig) BuildWithArgs(args []string) error {
failpoint.Inject("buildWithArgsErr", func() {
failpoint.Return(errors.New("fail to build with args"))
})
if len(args) < 1 {
return errs.ErrSchedulerConfig.FastGenByArgs("id")
}
@@ -386,8 +389,15 @@ func (handler *evictLeaderHandler) UpdateConfig(w http.ResponseWriter, r *http.R
args = append(args, handler.config.getRanges(id)...)
}

handler.config.BuildWithArgs(args)
err := handler.config.Persist()
err := handler.config.BuildWithArgs(args)
if err != nil {
handler.config.Lock()
handler.config.cluster.ResumeLeaderTransfer(id)
handler.config.Unlock()
handler.rd.JSON(w, http.StatusBadRequest, err.Error())
return
}
err = handler.config.Persist()
if err != nil {
handler.config.removeStore(id)
handler.rd.JSON(w, http.StatusInternalServerError, err.Error())
13 changes: 10 additions & 3 deletions pkg/schedule/schedulers/grant_leader.go
Original file line number Diff line number Diff line change
@@ -296,10 +296,17 @@ func (handler *grantLeaderHandler) UpdateConfig(w http.ResponseWriter, r *http.R
args = append(args, handler.config.getRanges(id)...)
}

handler.config.BuildWithArgs(args)
err := handler.config.Persist()
err := handler.config.BuildWithArgs(args)
if err != nil {
handler.config.removeStore(id)
handler.config.Lock()
handler.config.cluster.ResumeLeaderTransfer(id)
handler.config.Unlock()
handler.rd.JSON(w, http.StatusBadRequest, err.Error())
return
}
err = handler.config.Persist()
if err != nil {
_, _ = handler.config.removeStore(id)
handler.rd.JSON(w, http.StatusInternalServerError, err.Error())
return
}
16 changes: 14 additions & 2 deletions plugin/scheduler_example/evict_leader.go
Original file line number Diff line number Diff line change
@@ -275,9 +275,21 @@ func (handler *evictLeaderHandler) UpdateConfig(w http.ResponseWriter, r *http.R
args = append(args, handler.config.getRanges(id)...)
}

handler.config.BuildWithArgs(args)
err := handler.config.Persist()
err := handler.config.BuildWithArgs(args)
if err != nil {
handler.config.mu.Lock()
handler.config.cluster.ResumeLeaderTransfer(id)
handler.config.mu.Unlock()
handler.rd.JSON(w, http.StatusBadRequest, err.Error())
return
}

err = handler.config.Persist()
if err != nil {
handler.config.mu.Lock()
delete(handler.config.StoreIDWitRanges, id)
handler.config.cluster.ResumeLeaderTransfer(id)
handler.config.mu.Unlock()
handler.rd.JSON(w, http.StatusInternalServerError, err.Error())
}
handler.rd.JSON(w, http.StatusOK, nil)
87 changes: 87 additions & 0 deletions tools/pd-ctl/tests/scheduler/scheduler_test.go
Original file line number Diff line number Diff line change
@@ -722,6 +722,64 @@ func (suite *schedulerTestSuite) checkSchedulerDiagnostic(cluster *pdTests.TestC
checkSchedulerDescribeCommand("balance-leader-scheduler", "normal", "")
}

func (suite *schedulerTestSuite) TestEvictLeaderScheduler() {
suite.env.RunTestInTwoModes(suite.checkEvictLeaderScheduler)
}

func (suite *schedulerTestSuite) checkEvictLeaderScheduler(cluster *pdTests.TestCluster) {
re := suite.Require()
pdAddr := cluster.GetConfig().GetClientURL()
cmd := ctl.GetRootCmd()

stores := []*metapb.Store{
{
Id: 1,
State: metapb.StoreState_Up,
LastHeartbeat: time.Now().UnixNano(),
},
{
Id: 2,
State: metapb.StoreState_Up,
LastHeartbeat: time.Now().UnixNano(),
},
{
Id: 3,
State: metapb.StoreState_Up,
LastHeartbeat: time.Now().UnixNano(),
},
{
Id: 4,
State: metapb.StoreState_Up,
LastHeartbeat: time.Now().UnixNano(),
},
}
for _, store := range stores {
pdTests.MustPutStore(re, cluster, store)
}

pdTests.MustPutRegion(re, cluster, 1, 1, []byte("a"), []byte("b"))
suite.checkDefaultSchedulers(re, cmd, pdAddr)

output, err := tests.ExecuteCommand(cmd, []string{"-u", pdAddr, "scheduler", "add", "evict-leader-scheduler", "2"}...)
re.NoError(err)
re.Contains(string(output), "Success!")
failpoint.Enable("github.com/tikv/pd/pkg/schedule/schedulers/buildWithArgsErr", "return(true)")
output, err = tests.ExecuteCommand(cmd, []string{"-u", pdAddr, "scheduler", "add", "evict-leader-scheduler", "1"}...)
re.NoError(err)
re.Contains(string(output), "fail to build with args")
failpoint.Disable("github.com/tikv/pd/pkg/schedule/schedulers/buildWithArgsErr")
output, err = tests.ExecuteCommand(cmd, []string{"-u", pdAddr, "scheduler", "remove", "evict-leader-scheduler"}...)
re.NoError(err)
re.Contains(string(output), "Success!")
testutil.Eventually(re, func() bool {
output, err = tests.ExecuteCommand(cmd, []string{"-u", pdAddr, "scheduler", "add", "evict-leader-scheduler", "1"}...)
return err == nil && strings.Contains(string(output), "Success!")
})
output, err = tests.ExecuteCommand(cmd, []string{"-u", pdAddr, "scheduler", "remove", "evict-leader-scheduler-1"}...)
re.NoError(err)
re.Contains(string(output), "Success!")
}

func mustExec(re *require.Assertions, cmd *cobra.Command, args []string, v any) string {
output, err := tests.ExecuteCommand(cmd, args...)
re.NoError(err)
@@ -740,3 +798,32 @@ func mightExec(re *require.Assertions, cmd *cobra.Command, args []string, v any)
}
json.Unmarshal(output, v)
}

func (suite *schedulerTestSuite) checkDefaultSchedulers(re *require.Assertions, cmd *cobra.Command, pdAddr string) {
// scheduler show command
expected := make(map[string]bool)
for _, scheduler := range suite.defaultSchedulers {
expected[scheduler] = true
}
checkSchedulerCommand(re, cmd, pdAddr, nil, expected)
}

func checkSchedulerCommand(re *require.Assertions, cmd *cobra.Command, pdAddr string, args []string, expected map[string]bool) {
if args != nil {
echo := mustExec(re, cmd, args, nil)
re.Contains(echo, "Success!")
}
testutil.Eventually(re, func() bool {
var schedulers []string
mustExec(re, cmd, []string{"-u", pdAddr, "scheduler", "show"}, &schedulers)
if len(schedulers) != len(expected) {
return false
}
for _, scheduler := range schedulers {
if _, ok := expected[scheduler]; !ok {
return false
}
}
return true
})
}

0 comments on commit 57d5bdc

Please sign in to comment.