interaction_env_handler_propose_conf_change.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2019 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package rafttest
  15. import (
  16. "fmt"
  17. "strconv"
  18. "testing"
  19. "github.com/cockroachdb/datadriven"
  20. "go.etcd.io/etcd/raft/raftpb"
  21. )
  22. func (env *InteractionEnv) handleProposeConfChange(t *testing.T, d datadriven.TestData) error {
  23. idx := firstAsNodeIdx(t, d)
  24. var v1 bool
  25. transition := raftpb.ConfChangeTransitionAuto
  26. for _, arg := range d.CmdArgs[1:] {
  27. for _, val := range arg.Vals {
  28. switch arg.Key {
  29. case "v1":
  30. var err error
  31. v1, err = strconv.ParseBool(val)
  32. if err != nil {
  33. return err
  34. }
  35. case "transition":
  36. switch val {
  37. case "auto":
  38. transition = raftpb.ConfChangeTransitionAuto
  39. case "implicit":
  40. transition = raftpb.ConfChangeTransitionJointImplicit
  41. case "explicit":
  42. transition = raftpb.ConfChangeTransitionJointExplicit
  43. default:
  44. return fmt.Errorf("unknown transition %s", val)
  45. }
  46. default:
  47. return fmt.Errorf("unknown command %s", arg.Key)
  48. }
  49. }
  50. }
  51. ccs, err := raftpb.ConfChangesFromString(d.Input)
  52. if err != nil {
  53. return err
  54. }
  55. var c raftpb.ConfChangeI
  56. if v1 {
  57. if len(ccs) > 1 || transition != raftpb.ConfChangeTransitionAuto {
  58. return fmt.Errorf("v1 conf change can only have one operation and no transition")
  59. }
  60. c = raftpb.ConfChange{
  61. Type: ccs[0].Type,
  62. NodeID: ccs[0].NodeID,
  63. }
  64. } else {
  65. c = raftpb.ConfChangeV2{
  66. Transition: transition,
  67. Changes: ccs,
  68. }
  69. }
  70. return env.ProposeConfChange(idx, c)
  71. }
  72. // ProposeConfChange proposes a configuration change on the node with the given index.
  73. func (env *InteractionEnv) ProposeConfChange(idx int, c raftpb.ConfChangeI) error {
  74. return env.Nodes[idx].ProposeConfChange(c)
  75. }