interaction_env.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. "math"
  18. "strings"
  19. "go.etcd.io/etcd/raft"
  20. pb "go.etcd.io/etcd/raft/raftpb"
  21. )
  22. // InteractionOpts groups the options for an InteractionEnv.
  23. type InteractionOpts struct {
  24. OnConfig func(*raft.Config)
  25. }
  26. // A Node is a member of a raft group tested via an InteractionEnv.
  27. type Node struct {
  28. *raft.RawNode
  29. Storage
  30. Config *raft.Config
  31. History []pb.Snapshot
  32. }
  33. // InteractionEnv facilitates testing of complex interactions between the
  34. // members of a raft group.
  35. type InteractionEnv struct {
  36. Options *InteractionOpts
  37. Nodes []Node
  38. Messages []pb.Message // in-flight messages
  39. Output *RedirectLogger
  40. }
  41. // NewInteractionEnv initializes an InteractionEnv. opts may be nil.
  42. func NewInteractionEnv(opts *InteractionOpts) *InteractionEnv {
  43. if opts == nil {
  44. opts = &InteractionOpts{}
  45. }
  46. return &InteractionEnv{
  47. Options: opts,
  48. Output: &RedirectLogger{
  49. Builder: &strings.Builder{},
  50. },
  51. }
  52. }
  53. // Storage is the interface used by InteractionEnv. It is comprised of raft's
  54. // Storage interface plus access to operations that maintain the log and drive
  55. // the Ready handling loop.
  56. type Storage interface {
  57. raft.Storage
  58. SetHardState(state pb.HardState) error
  59. ApplySnapshot(pb.Snapshot) error
  60. Compact(newFirstIndex uint64) error
  61. Append([]pb.Entry) error
  62. }
  63. // defaultRaftConfig sets up a *raft.Config with reasonable testing defaults.
  64. // In particular, no limits are set.
  65. func defaultRaftConfig(id uint64, applied uint64, s raft.Storage) *raft.Config {
  66. return &raft.Config{
  67. ID: id,
  68. Applied: applied,
  69. ElectionTick: 3,
  70. HeartbeatTick: 1,
  71. Storage: s,
  72. MaxSizePerMsg: math.MaxUint64,
  73. MaxInflightMsgs: math.MaxInt32,
  74. }
  75. }
  76. func defaultEntryFormatter(b []byte) string {
  77. return fmt.Sprintf("%q", b)
  78. }