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