progress_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Copyright 2015 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 tracker
  15. import (
  16. "testing"
  17. )
  18. func TestProgressIsPaused(t *testing.T) {
  19. tests := []struct {
  20. state StateType
  21. paused bool
  22. w bool
  23. }{
  24. {StateProbe, false, false},
  25. {StateProbe, true, true},
  26. {StateReplicate, false, false},
  27. {StateReplicate, true, false},
  28. {StateSnapshot, false, true},
  29. {StateSnapshot, true, true},
  30. }
  31. for i, tt := range tests {
  32. p := &Progress{
  33. State: tt.state,
  34. ProbeSent: tt.paused,
  35. Inflights: NewInflights(256),
  36. }
  37. if g := p.IsPaused(); g != tt.w {
  38. t.Errorf("#%d: paused= %t, want %t", i, g, tt.w)
  39. }
  40. }
  41. }
  42. // TestProgressResume ensures that MaybeUpdate and MaybeDecrTo will reset
  43. // ProbeSent.
  44. func TestProgressResume(t *testing.T) {
  45. p := &Progress{
  46. Next: 2,
  47. ProbeSent: true,
  48. }
  49. p.MaybeDecrTo(1, 1)
  50. if p.ProbeSent {
  51. t.Errorf("paused= %v, want false", p.ProbeSent)
  52. }
  53. p.ProbeSent = true
  54. p.MaybeUpdate(2)
  55. if p.ProbeSent {
  56. t.Errorf("paused= %v, want false", p.ProbeSent)
  57. }
  58. }
  59. func TestProgressBecomeProbe(t *testing.T) {
  60. match := uint64(1)
  61. tests := []struct {
  62. p *Progress
  63. wnext uint64
  64. }{
  65. {
  66. &Progress{State: StateReplicate, Match: match, Next: 5, Inflights: NewInflights(256)},
  67. 2,
  68. },
  69. {
  70. // snapshot finish
  71. &Progress{State: StateSnapshot, Match: match, Next: 5, PendingSnapshot: 10, Inflights: NewInflights(256)},
  72. 11,
  73. },
  74. {
  75. // snapshot failure
  76. &Progress{State: StateSnapshot, Match: match, Next: 5, PendingSnapshot: 0, Inflights: NewInflights(256)},
  77. 2,
  78. },
  79. }
  80. for i, tt := range tests {
  81. tt.p.BecomeProbe()
  82. if tt.p.State != StateProbe {
  83. t.Errorf("#%d: state = %s, want %s", i, tt.p.State, StateProbe)
  84. }
  85. if tt.p.Match != match {
  86. t.Errorf("#%d: match = %d, want %d", i, tt.p.Match, match)
  87. }
  88. if tt.p.Next != tt.wnext {
  89. t.Errorf("#%d: next = %d, want %d", i, tt.p.Next, tt.wnext)
  90. }
  91. }
  92. }
  93. func TestProgressBecomeReplicate(t *testing.T) {
  94. p := &Progress{State: StateProbe, Match: 1, Next: 5, Inflights: NewInflights(256)}
  95. p.BecomeReplicate()
  96. if p.State != StateReplicate {
  97. t.Errorf("state = %s, want %s", p.State, StateReplicate)
  98. }
  99. if p.Match != 1 {
  100. t.Errorf("match = %d, want 1", p.Match)
  101. }
  102. if w := p.Match + 1; p.Next != w {
  103. t.Errorf("next = %d, want %d", p.Next, w)
  104. }
  105. }
  106. func TestProgressBecomeSnapshot(t *testing.T) {
  107. p := &Progress{State: StateProbe, Match: 1, Next: 5, Inflights: NewInflights(256)}
  108. p.BecomeSnapshot(10)
  109. if p.State != StateSnapshot {
  110. t.Errorf("state = %s, want %s", p.State, StateSnapshot)
  111. }
  112. if p.Match != 1 {
  113. t.Errorf("match = %d, want 1", p.Match)
  114. }
  115. if p.PendingSnapshot != 10 {
  116. t.Errorf("pendingSnapshot = %d, want 10", p.PendingSnapshot)
  117. }
  118. }
  119. func TestProgressUpdate(t *testing.T) {
  120. prevM, prevN := uint64(3), uint64(5)
  121. tests := []struct {
  122. update uint64
  123. wm uint64
  124. wn uint64
  125. wok bool
  126. }{
  127. {prevM - 1, prevM, prevN, false}, // do not decrease match, next
  128. {prevM, prevM, prevN, false}, // do not decrease next
  129. {prevM + 1, prevM + 1, prevN, true}, // increase match, do not decrease next
  130. {prevM + 2, prevM + 2, prevN + 1, true}, // increase match, next
  131. }
  132. for i, tt := range tests {
  133. p := &Progress{
  134. Match: prevM,
  135. Next: prevN,
  136. }
  137. ok := p.MaybeUpdate(tt.update)
  138. if ok != tt.wok {
  139. t.Errorf("#%d: ok= %v, want %v", i, ok, tt.wok)
  140. }
  141. if p.Match != tt.wm {
  142. t.Errorf("#%d: match= %d, want %d", i, p.Match, tt.wm)
  143. }
  144. if p.Next != tt.wn {
  145. t.Errorf("#%d: next= %d, want %d", i, p.Next, tt.wn)
  146. }
  147. }
  148. }
  149. func TestProgressMaybeDecr(t *testing.T) {
  150. tests := []struct {
  151. state StateType
  152. m uint64
  153. n uint64
  154. rejected uint64
  155. last uint64
  156. w bool
  157. wn uint64
  158. }{
  159. {
  160. // state replicate and rejected is not greater than match
  161. StateReplicate, 5, 10, 5, 5, false, 10,
  162. },
  163. {
  164. // state replicate and rejected is not greater than match
  165. StateReplicate, 5, 10, 4, 4, false, 10,
  166. },
  167. {
  168. // state replicate and rejected is greater than match
  169. // directly decrease to match+1
  170. StateReplicate, 5, 10, 9, 9, true, 6,
  171. },
  172. {
  173. // next-1 != rejected is always false
  174. StateProbe, 0, 0, 0, 0, false, 0,
  175. },
  176. {
  177. // next-1 != rejected is always false
  178. StateProbe, 0, 10, 5, 5, false, 10,
  179. },
  180. {
  181. // next>1 = decremented by 1
  182. StateProbe, 0, 10, 9, 9, true, 9,
  183. },
  184. {
  185. // next>1 = decremented by 1
  186. StateProbe, 0, 2, 1, 1, true, 1,
  187. },
  188. {
  189. // next<=1 = reset to 1
  190. StateProbe, 0, 1, 0, 0, true, 1,
  191. },
  192. {
  193. // decrease to min(rejected, last+1)
  194. StateProbe, 0, 10, 9, 2, true, 3,
  195. },
  196. {
  197. // rejected < 1, reset to 1
  198. StateProbe, 0, 10, 9, 0, true, 1,
  199. },
  200. }
  201. for i, tt := range tests {
  202. p := &Progress{
  203. State: tt.state,
  204. Match: tt.m,
  205. Next: tt.n,
  206. }
  207. if g := p.MaybeDecrTo(tt.rejected, tt.last); g != tt.w {
  208. t.Errorf("#%d: maybeDecrTo= %t, want %t", i, g, tt.w)
  209. }
  210. if gm := p.Match; gm != tt.m {
  211. t.Errorf("#%d: match= %d, want %d", i, gm, tt.m)
  212. }
  213. if gn := p.Next; gn != tt.wn {
  214. t.Errorf("#%d: next= %d, want %d", i, gn, tt.wn)
  215. }
  216. }
  217. }