subscriber_test.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package discov
  2. import (
  3. "sync/atomic"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/tal-tech/go-zero/core/discov/internal"
  7. )
  8. const (
  9. actionAdd = iota
  10. actionDel
  11. )
  12. func TestContainer(t *testing.T) {
  13. type action struct {
  14. act int
  15. key string
  16. val string
  17. }
  18. tests := []struct {
  19. name string
  20. do []action
  21. expect []string
  22. }{
  23. {
  24. name: "add one",
  25. do: []action{
  26. {
  27. act: actionAdd,
  28. key: "first",
  29. val: "a",
  30. },
  31. },
  32. expect: []string{
  33. "a",
  34. },
  35. },
  36. {
  37. name: "add two",
  38. do: []action{
  39. {
  40. act: actionAdd,
  41. key: "first",
  42. val: "a",
  43. },
  44. {
  45. act: actionAdd,
  46. key: "second",
  47. val: "b",
  48. },
  49. },
  50. expect: []string{
  51. "a",
  52. "b",
  53. },
  54. },
  55. {
  56. name: "add two, delete one",
  57. do: []action{
  58. {
  59. act: actionAdd,
  60. key: "first",
  61. val: "a",
  62. },
  63. {
  64. act: actionAdd,
  65. key: "second",
  66. val: "b",
  67. },
  68. {
  69. act: actionDel,
  70. key: "first",
  71. },
  72. },
  73. expect: []string{"b"},
  74. },
  75. {
  76. name: "add two, delete two",
  77. do: []action{
  78. {
  79. act: actionAdd,
  80. key: "first",
  81. val: "a",
  82. },
  83. {
  84. act: actionAdd,
  85. key: "second",
  86. val: "b",
  87. },
  88. {
  89. act: actionDel,
  90. key: "first",
  91. },
  92. {
  93. act: actionDel,
  94. key: "second",
  95. },
  96. },
  97. expect: []string{},
  98. },
  99. {
  100. name: "add three, dup values, delete two",
  101. do: []action{
  102. {
  103. act: actionAdd,
  104. key: "first",
  105. val: "a",
  106. },
  107. {
  108. act: actionAdd,
  109. key: "second",
  110. val: "b",
  111. },
  112. {
  113. act: actionAdd,
  114. key: "third",
  115. val: "a",
  116. },
  117. {
  118. act: actionDel,
  119. key: "first",
  120. },
  121. {
  122. act: actionDel,
  123. key: "second",
  124. },
  125. },
  126. expect: []string{"a"},
  127. },
  128. {
  129. name: "add three, dup values, delete two, delete not added",
  130. do: []action{
  131. {
  132. act: actionAdd,
  133. key: "first",
  134. val: "a",
  135. },
  136. {
  137. act: actionAdd,
  138. key: "second",
  139. val: "b",
  140. },
  141. {
  142. act: actionAdd,
  143. key: "third",
  144. val: "a",
  145. },
  146. {
  147. act: actionDel,
  148. key: "first",
  149. },
  150. {
  151. act: actionDel,
  152. key: "second",
  153. },
  154. {
  155. act: actionDel,
  156. key: "forth",
  157. },
  158. },
  159. expect: []string{"a"},
  160. },
  161. }
  162. exclusives := []bool{true, false}
  163. for _, test := range tests {
  164. for _, exclusive := range exclusives {
  165. t.Run(test.name, func(t *testing.T) {
  166. var changed bool
  167. c := newContainer(exclusive)
  168. c.addListener(func() {
  169. changed = true
  170. })
  171. assert.Nil(t, c.getValues())
  172. assert.False(t, changed)
  173. for _, order := range test.do {
  174. if order.act == actionAdd {
  175. c.OnAdd(internal.KV{
  176. Key: order.key,
  177. Val: order.val,
  178. })
  179. } else {
  180. c.OnDelete(internal.KV{
  181. Key: order.key,
  182. Val: order.val,
  183. })
  184. }
  185. }
  186. assert.True(t, changed)
  187. assert.True(t, c.dirty.True())
  188. assert.ElementsMatch(t, test.expect, c.getValues())
  189. assert.False(t, c.dirty.True())
  190. assert.ElementsMatch(t, test.expect, c.getValues())
  191. })
  192. }
  193. }
  194. }
  195. func TestSubscriber(t *testing.T) {
  196. var opt subOptions
  197. Exclusive()(&opt)
  198. sub := new(Subscriber)
  199. sub.items = newContainer(opt.exclusive)
  200. var count int32
  201. sub.AddListener(func() {
  202. atomic.AddInt32(&count, 1)
  203. })
  204. sub.items.notifyChange()
  205. assert.Empty(t, sub.Values())
  206. assert.Equal(t, int32(1), atomic.LoadInt32(&count))
  207. }