subscriber_test.go 3.7 KB

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