106ba6c3387717da913a019297a0b7cb7f04cebb
[ric-plt/sdlgo.git] / internal / sdlgoredis / sdlgoredis_test.go
1 /*
2    Copyright (c) 2019 AT&T Intellectual Property.
3    Copyright (c) 2018-2022 Nokia.
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 */
17
18 /*
19  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23 package sdlgoredis_test
24
25 import (
26         "context"
27         "errors"
28         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
29         "github.com/go-redis/redis/v8"
30         "github.com/stretchr/testify/assert"
31         "github.com/stretchr/testify/mock"
32         "strconv"
33         "testing"
34         "time"
35 )
36
37 type clientMock struct {
38         mock.Mock
39 }
40
41 type pubSubMock struct {
42         mock.Mock
43 }
44
45 type MockOS struct {
46         mock.Mock
47 }
48
49 func (m *pubSubMock) Channel(opts ...redis.ChannelOption) <-chan *redis.Message {
50         return m.Called().Get(0).(chan *redis.Message)
51 }
52
53 func (m *pubSubMock) Subscribe(ctx context.Context, channels ...string) error {
54         return m.Called().Error(0)
55 }
56
57 func (m *pubSubMock) Unsubscribe(ctx context.Context, channels ...string) error {
58         return m.Called().Error(0)
59 }
60
61 func (m *pubSubMock) Close() error {
62         return m.Called().Error(0)
63 }
64
65 func (m *clientMock) Command(ctx context.Context) *redis.CommandsInfoCmd {
66         return m.Called().Get(0).(*redis.CommandsInfoCmd)
67 }
68
69 func (m *clientMock) Close() error {
70         return m.Called().Error(0)
71 }
72
73 func (m *clientMock) Subscribe(ctx context.Context, channels ...string) *redis.PubSub {
74         return m.Called(channels).Get(0).(*redis.PubSub)
75 }
76
77 func (m *clientMock) MSet(ctx context.Context, pairs ...interface{}) *redis.StatusCmd {
78         return m.Called(pairs).Get(0).(*redis.StatusCmd)
79 }
80
81 func (m *clientMock) Do(ctx context.Context, args ...interface{}) *redis.Cmd {
82         return m.Called(args).Get(0).(*redis.Cmd)
83 }
84
85 func (m *clientMock) MGet(ctx context.Context, keys ...string) *redis.SliceCmd {
86         return m.Called(keys).Get(0).(*redis.SliceCmd)
87 }
88
89 func (m *clientMock) Del(ctx context.Context, keys ...string) *redis.IntCmd {
90         return m.Called(keys).Get(0).(*redis.IntCmd)
91 }
92
93 func (m *clientMock) Keys(ctx context.Context, pattern string) *redis.StringSliceCmd {
94         return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
95 }
96
97 func (m *clientMock) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
98         return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
99 }
100
101 func (m *clientMock) SAdd(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
102         return m.Called(key, members).Get(0).(*redis.IntCmd)
103 }
104
105 func (m *clientMock) SRem(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
106         return m.Called(key, members).Get(0).(*redis.IntCmd)
107 }
108
109 func (m *clientMock) SMembers(ctx context.Context, key string) *redis.StringSliceCmd {
110         return m.Called(key).Get(0).(*redis.StringSliceCmd)
111 }
112
113 func (m *clientMock) SIsMember(ctx context.Context, key string, member interface{}) *redis.BoolCmd {
114         return m.Called(key, member).Get(0).(*redis.BoolCmd)
115 }
116
117 func (m *clientMock) SCard(ctx context.Context, key string) *redis.IntCmd {
118         return m.Called(key).Get(0).(*redis.IntCmd)
119 }
120
121 func (m *clientMock) PTTL(ctx context.Context, key string) *redis.DurationCmd {
122         return m.Called(key).Get(0).(*redis.DurationCmd)
123 }
124
125 func (m *clientMock) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd {
126         return m.Called(script, keys).Get(0).(*redis.Cmd)
127 }
128
129 func (m *clientMock) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd {
130         return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
131 }
132
133 func (m *clientMock) ScriptExists(ctx context.Context, scripts ...string) *redis.BoolSliceCmd {
134         return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
135 }
136
137 func (m *clientMock) ScriptLoad(ctx context.Context, script string) *redis.StringCmd {
138         return m.Called(script).Get(0).(*redis.StringCmd)
139 }
140
141 func (m *clientMock) Info(ctx context.Context, section ...string) *redis.StringCmd {
142         return m.Called(section).Get(0).(*redis.StringCmd)
143 }
144
145 type MockRedisSentinel struct {
146         mock.Mock
147 }
148
149 func (m *MockRedisSentinel) Master(ctx context.Context, name string) *redis.StringStringMapCmd {
150         a := m.Called(name)
151         return a.Get(0).(*redis.StringStringMapCmd)
152 }
153
154 func (m *MockRedisSentinel) Slaves(ctx context.Context, name string) *redis.SliceCmd {
155         a := m.Called(name)
156         return a.Get(0).(*redis.SliceCmd)
157 }
158
159 func (m *MockRedisSentinel) Sentinels(ctx context.Context, name string) *redis.SliceCmd {
160         a := m.Called(name)
161         return a.Get(0).(*redis.SliceCmd)
162 }
163
164 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
165         mock := new(pubSubMock)
166         return mock, func(ctx context.Context, client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
167                 return mock
168         }
169 }
170
171 func (m *MockOS) Getenv(key string, defValue string) string {
172         a := m.Called(key, defValue)
173         return a.String(0)
174 }
175
176 type setupEv struct {
177         pubSubMock []*pubSubMock
178         rClient    []*clientMock
179         rSentinel  []*MockRedisSentinel
180         db         []*sdlgoredis.DB
181 }
182
183 func setupHaEnv(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
184         psm, cm, _, db := setupHaEnvWithSentinels(commandsExists, "3")
185         return psm, cm, db
186 }
187
188 func setupHaEnvWithSentinels(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, []*MockRedisSentinel, *sdlgoredis.DB) {
189         setupVals := setupEnv(
190                 commandsExists,
191                 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
192                 "6379",
193                 "dbaasmaster-cluster-0",
194                 "26379",
195                 "",
196                 nodeCnt,
197         )
198         return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.rSentinel, setupVals.db[0]
199 }
200
201 func setupSingleEnv(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
202         setupVals := setupEnv(
203                 commandsExists,
204                 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
205                 "6379", "", "", "", nodeCnt,
206         )
207         return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
208 }
209
210 func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nodeCnt string) setupEv {
211         var ret setupEv
212
213         dummyCommandInfo := redis.CommandInfo{
214                 Name: "dummy",
215         }
216
217         cmdResult := make(map[string]*redis.CommandInfo, 0)
218         if commandsExists {
219                 cmdResult = map[string]*redis.CommandInfo{
220                         "setie":    &dummyCommandInfo,
221                         "delie":    &dummyCommandInfo,
222                         "setiepub": &dummyCommandInfo,
223                         "setnxpub": &dummyCommandInfo,
224                         "msetmpub": &dummyCommandInfo,
225                         "delmpub":  &dummyCommandInfo,
226                 }
227         } else {
228                 cmdResult = map[string]*redis.CommandInfo{
229                         "dummy": &dummyCommandInfo,
230                 }
231         }
232
233         osmock := new(MockOS)
234         osmock.On("Getenv", "DBAAS_SERVICE_HOST", "localhost").Return(host)
235         osmock.On("Getenv", "DBAAS_SERVICE_PORT", "6379").Return(port)
236         osmock.On("Getenv", "DBAAS_MASTER_NAME", "").Return(msname)
237         osmock.On("Getenv", "DBAAS_SERVICE_SENTINEL_PORT", "").Return(sntport)
238         osmock.On("Getenv", "DBAAS_CLUSTER_ADDR_LIST", "").Return(clsaddrlist)
239         osmock.On("Getenv", "DBAAS_NODE_COUNT", "1").Return(nodeCnt)
240
241         pubSubMock, subscribeNotifications := setSubscribeNotifications()
242         smock := new(MockRedisSentinel)
243         ret.rSentinel = append(ret.rSentinel, smock)
244         clients := sdlgoredis.ReadConfigAndCreateDbClients(
245                 osmock,
246                 func(addr, port, clusterName string, isHa bool) sdlgoredis.RedisClient {
247                         clm := new(clientMock)
248                         clm.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
249                         ret.rClient = append(ret.rClient, clm)
250                         ret.pubSubMock = append(ret.pubSubMock, pubSubMock)
251                         return clm
252                 },
253                 subscribeNotifications,
254                 func(addr, sentinelPort, masterName, nodeCnt string) *sdlgoredis.Sentinel {
255                         s := &sdlgoredis.Sentinel{
256                                 IredisSentinelClient: smock,
257                                 MasterName:           masterName,
258                                 NodeCnt:              nodeCnt,
259                         }
260                         return s
261                 },
262         )
263         ret.db = clients
264         return ret
265 }
266
267 func newMockRedisMasterCallResp(role, ip, port, flag string) map[string]string {
268         resp := map[string]string{}
269         if role != "" {
270                 resp["role-reported"] = role
271                 resp["ip"] = ip
272                 resp["port"] = port
273                 resp["flags"] = flag
274         }
275         return resp
276 }
277
278 type mockRedisSlaves struct {
279         resp []interface{}
280 }
281
282 func newMockRedisSlavesCall() *mockRedisSlaves {
283         return new(mockRedisSlaves)
284 }
285
286 func (mrr *mockRedisSlaves) add(role, ip, port, link, flag string) {
287         mrr.resp = append(mrr.resp,
288                 []interface{}{
289                         "role-reported", role,
290                         "ip", ip,
291                         "port", port,
292                         "master-link-status", link,
293                         "flags", flag,
294                 },
295         )
296 }
297
298 type mockRedisSentinels struct {
299         resp []interface{}
300 }
301
302 func newMockRedisSentinelsCall() *mockRedisSentinels {
303         return new(mockRedisSentinels)
304 }
305
306 func (mrs *mockRedisSentinels) add(ip, port, flag string) {
307         mrs.resp = append(mrs.resp,
308                 []interface{}{
309                         "ip", ip,
310                         "port", port,
311                         "flags", flag,
312                 },
313         )
314 }
315
316 type ExpDbState struct {
317         s sdlgoredis.DbState
318 }
319
320 func newExpDbState(nodeCnt int, err error) *ExpDbState {
321         state := new(ExpDbState)
322         state.s.ConfigNodeCnt = nodeCnt
323         state.s.Err = err
324         return state
325 }
326
327 func (edbs *ExpDbState) addPrimary(role, ip, port, flag string, err error) {
328         edbs.s.PrimaryDbState.Err = err
329         edbs.s.PrimaryDbState.Fields = sdlgoredis.PrimaryDbStateFields{
330                 Role:  role,
331                 Ip:    ip,
332                 Port:  port,
333                 Flags: flag,
334         }
335 }
336
337 func (edbs *ExpDbState) addReplica(role, ip, port, link, flag string, err error) {
338         if edbs.s.ReplicasDbState == nil {
339                 edbs.s.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
340                 edbs.s.ReplicasDbState.States = make([]*sdlgoredis.ReplicaDbState, 0)
341         }
342         edbs.s.ReplicasDbState.Err = err
343         if ip != "" || port != "" || link != "" || flag != "" {
344                 edbs.s.ReplicasDbState.States = append(edbs.s.ReplicasDbState.States,
345                         &sdlgoredis.ReplicaDbState{
346                                 Fields: sdlgoredis.ReplicaDbStateFields{
347                                         Role:              role,
348                                         Ip:                ip,
349                                         Port:              port,
350                                         PrimaryLinkStatus: link,
351                                         Flags:             flag,
352                                 },
353                         },
354                 )
355         }
356 }
357
358 func (edbs *ExpDbState) addSentinel(ip, port, flag string, err error) {
359         if edbs.s.SentinelsDbState == nil {
360                 edbs.s.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
361                 edbs.s.SentinelsDbState.States = make([]*sdlgoredis.SentinelDbState, 0)
362         }
363         edbs.s.SentinelsDbState.Err = err
364         if ip != "" || port != "" || flag != "" {
365                 edbs.s.SentinelsDbState.States = append(edbs.s.SentinelsDbState.States,
366                         &sdlgoredis.SentinelDbState{
367                                 Fields: sdlgoredis.SentinelDbStateFields{
368                                         Ip:    ip,
369                                         Port:  port,
370                                         Flags: flag,
371                                 },
372                         },
373                 )
374         }
375 }
376
377 func TestCloseDbSuccessfully(t *testing.T) {
378         _, r, db := setupHaEnv(true)
379         r.On("Close").Return(nil)
380         err := db.CloseDB()
381         assert.Nil(t, err)
382         r.AssertExpectations(t)
383 }
384
385 func TestCloseDbFailure(t *testing.T) {
386         _, r, db := setupHaEnv(true)
387         r.On("Close").Return(errors.New("Some error"))
388         err := db.CloseDB()
389         assert.NotNil(t, err)
390         r.AssertExpectations(t)
391 }
392
393 func TestMSetSuccessfully(t *testing.T) {
394         _, r, db := setupHaEnv(true)
395         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
396         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
397         err := db.MSet("key1", "value1", "key2", 2)
398         assert.Nil(t, err)
399         r.AssertExpectations(t)
400 }
401
402 func TestMSetFailure(t *testing.T) {
403         _, r, db := setupHaEnv(true)
404         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
405         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
406         err := db.MSet("key1", "value1", "key2", 2)
407         assert.NotNil(t, err)
408         r.AssertExpectations(t)
409 }
410
411 func TestMSetMPubSuccessfully(t *testing.T) {
412         _, r, db := setupHaEnv(true)
413         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
414                 "chan1", "event1", "chan2", "event2"}
415         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
416         assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
417                 "key1", "val1", "key2", "val2"))
418         r.AssertExpectations(t)
419 }
420
421 func TestMsetMPubFailure(t *testing.T) {
422         _, r, db := setupHaEnv(true)
423         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
424                 "chan1", "event1", "chan2", "event2"}
425         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
426         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
427                 "key1", "val1", "key2", "val2"))
428         r.AssertExpectations(t)
429 }
430
431 func TestMSetMPubCommandMissing(t *testing.T) {
432         _, r, db := setupHaEnv(false)
433         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
434                 "chan1", "event1", "chan2", "event2"}
435         r.AssertNotCalled(t, "Do", expectedMessage)
436         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
437                 "key1", "val1", "key2", "val2"))
438         r.AssertExpectations(t)
439
440 }
441
442 func TestMGetSuccessfully(t *testing.T) {
443         _, r, db := setupHaEnv(true)
444         expectedKeys := []string{"key1", "key2", "key3"}
445         expectedResult := []interface{}{"val1", 2, nil}
446         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
447         result, err := db.MGet([]string{"key1", "key2", "key3"})
448         assert.Equal(t, result, expectedResult)
449         assert.Nil(t, err)
450         r.AssertExpectations(t)
451 }
452
453 func TestMGetFailure(t *testing.T) {
454         _, r, db := setupHaEnv(true)
455         expectedKeys := []string{"key1", "key2", "key3"}
456         expectedResult := []interface{}{nil}
457         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
458                 errors.New("Some error")))
459         result, err := db.MGet([]string{"key1", "key2", "key3"})
460         assert.Equal(t, result, expectedResult)
461         assert.NotNil(t, err)
462         r.AssertExpectations(t)
463 }
464
465 func TestDelMPubSuccessfully(t *testing.T) {
466         _, r, db := setupHaEnv(true)
467         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
468                 "chan2", "event2"}
469         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
470         assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
471                 []string{"key1", "key2"}))
472         r.AssertExpectations(t)
473 }
474
475 func TestDelMPubFailure(t *testing.T) {
476         _, r, db := setupHaEnv(true)
477         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
478                 "chan2", "event2"}
479         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
480         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
481                 []string{"key1", "key2"}))
482         r.AssertExpectations(t)
483 }
484
485 func TestDelMPubCommandMissing(t *testing.T) {
486         _, r, db := setupHaEnv(false)
487         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
488                 "chan2", "event2"}
489         r.AssertNotCalled(t, "Do", expectedMessage)
490         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
491                 []string{"key1", "key2"}))
492         r.AssertExpectations(t)
493 }
494
495 func TestDelSuccessfully(t *testing.T) {
496         _, r, db := setupHaEnv(true)
497         expectedKeys := []string{"key1", "key2"}
498         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
499         assert.Nil(t, db.Del([]string{"key1", "key2"}))
500         r.AssertExpectations(t)
501 }
502
503 func TestDelFailure(t *testing.T) {
504         _, r, db := setupHaEnv(true)
505         expectedKeys := []string{"key1", "key2"}
506         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
507         assert.NotNil(t, db.Del([]string{"key1", "key2"}))
508         r.AssertExpectations(t)
509 }
510
511 func TestKeysSuccessfully(t *testing.T) {
512         _, r, db := setupHaEnv(true)
513         expectedPattern := "pattern*"
514         expectedResult := []string{"pattern1", "pattern2"}
515         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
516         result, err := db.Keys("pattern*")
517         assert.Equal(t, result, expectedResult)
518         assert.Nil(t, err)
519         r.AssertExpectations(t)
520 }
521
522 func TestKeysFailure(t *testing.T) {
523         _, r, db := setupHaEnv(true)
524         expectedPattern := "pattern*"
525         expectedResult := []string{}
526         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
527                 errors.New("Some error")))
528         _, err := db.Keys("pattern*")
529         assert.NotNil(t, err)
530         r.AssertExpectations(t)
531 }
532
533 func TestSetIEKeyExists(t *testing.T) {
534         _, r, db := setupHaEnv(true)
535         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
536         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
537         result, err := db.SetIE("key", "olddata", "newdata")
538         assert.True(t, result)
539         assert.Nil(t, err)
540         r.AssertExpectations(t)
541 }
542
543 func TestSetIEKeyDoesntExists(t *testing.T) {
544         _, r, db := setupHaEnv(true)
545         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
546         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
547         result, err := db.SetIE("key", "olddata", "newdata")
548         assert.False(t, result)
549         assert.Nil(t, err)
550         r.AssertExpectations(t)
551 }
552
553 func TestSetIEFailure(t *testing.T) {
554         _, r, db := setupHaEnv(true)
555         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
556         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
557         result, err := db.SetIE("key", "olddata", "newdata")
558         assert.False(t, result)
559         assert.NotNil(t, err)
560         r.AssertExpectations(t)
561 }
562
563 func TestSetIECommandMissing(t *testing.T) {
564         _, r, db := setupHaEnv(false)
565         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
566         r.AssertNotCalled(t, "Do", expectedMessage)
567         result, err := db.SetIE("key", "olddata", "newdata")
568         assert.False(t, result)
569         assert.NotNil(t, err)
570         r.AssertExpectations(t)
571 }
572
573 func TestSetIEPubKeyExists(t *testing.T) {
574         _, r, db := setupHaEnv(true)
575         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
576         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
577         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
578         assert.True(t, result)
579         assert.Nil(t, err)
580         r.AssertExpectations(t)
581 }
582
583 func TestSetIEPubKeyDoesntExists(t *testing.T) {
584         _, r, db := setupHaEnv(true)
585         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
586         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
587         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
588         assert.False(t, result)
589         assert.Nil(t, err)
590         r.AssertExpectations(t)
591 }
592
593 func TestSetIEPubFailure(t *testing.T) {
594         _, r, db := setupHaEnv(true)
595         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
596         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
597         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
598         assert.False(t, result)
599         assert.NotNil(t, err)
600         r.AssertExpectations(t)
601 }
602
603 func TestSetIEPubCommandMissing(t *testing.T) {
604         _, r, db := setupHaEnv(false)
605         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
606         r.AssertNotCalled(t, "Do", expectedMessage)
607         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
608         assert.False(t, result)
609         assert.NotNil(t, err)
610         r.AssertExpectations(t)
611 }
612
613 func TestSetNXPubKeyDoesntExist(t *testing.T) {
614         _, r, db := setupHaEnv(true)
615         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
616         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
617         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
618         assert.True(t, result)
619         assert.Nil(t, err)
620         r.AssertExpectations(t)
621 }
622
623 func TestSetNXPubKeyExists(t *testing.T) {
624         _, r, db := setupHaEnv(true)
625         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
626         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
627         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
628         assert.False(t, result)
629         assert.Nil(t, err)
630         r.AssertExpectations(t)
631 }
632
633 func TestSetNXPubFailure(t *testing.T) {
634         _, r, db := setupHaEnv(true)
635         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
636         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
637         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
638         assert.False(t, result)
639         assert.NotNil(t, err)
640         r.AssertExpectations(t)
641 }
642
643 func TestSetNXPubCommandMissing(t *testing.T) {
644         _, r, db := setupHaEnv(false)
645         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
646         r.AssertNotCalled(t, "Do", expectedMessage)
647         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
648         assert.False(t, result)
649         assert.NotNil(t, err)
650         r.AssertExpectations(t)
651 }
652
653 func TestSetNXSuccessfully(t *testing.T) {
654         _, r, db := setupHaEnv(true)
655         expectedKey := "key"
656         expectedData := "data"
657         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
658         result, err := db.SetNX("key", "data", 0)
659         assert.True(t, result)
660         assert.Nil(t, err)
661         r.AssertExpectations(t)
662 }
663
664 func TestSetNXUnsuccessfully(t *testing.T) {
665         _, r, db := setupHaEnv(true)
666         expectedKey := "key"
667         expectedData := "data"
668         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
669         result, err := db.SetNX("key", "data", 0)
670         assert.False(t, result)
671         assert.Nil(t, err)
672         r.AssertExpectations(t)
673 }
674
675 func TestSetNXFailure(t *testing.T) {
676         _, r, db := setupHaEnv(true)
677         expectedKey := "key"
678         expectedData := "data"
679         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
680                 Return(redis.NewBoolResult(false, errors.New("Some error")))
681         result, err := db.SetNX("key", "data", 0)
682         assert.False(t, result)
683         assert.NotNil(t, err)
684         r.AssertExpectations(t)
685 }
686
687 func TestDelIEPubKeyDoesntExist(t *testing.T) {
688         _, r, db := setupHaEnv(true)
689         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
690         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
691         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
692         assert.False(t, result)
693         assert.Nil(t, err)
694         r.AssertExpectations(t)
695 }
696
697 func TestDelIEPubKeyExists(t *testing.T) {
698         _, r, db := setupHaEnv(true)
699         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
700         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
701         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
702         assert.True(t, result)
703         assert.Nil(t, err)
704         r.AssertExpectations(t)
705 }
706
707 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
708         _, r, db := setupHaEnv(true)
709         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
710         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
711         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
712         assert.True(t, result)
713         assert.Nil(t, err)
714         r.AssertExpectations(t)
715 }
716
717 func TestDelIEPubFailure(t *testing.T) {
718         _, r, db := setupHaEnv(true)
719         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
720         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
721         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
722         assert.False(t, result)
723         assert.NotNil(t, err)
724         r.AssertExpectations(t)
725 }
726
727 func TestDelIEPubCommandMissing(t *testing.T) {
728         _, r, db := setupHaEnv(false)
729         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
730         r.AssertNotCalled(t, "Do", expectedMessage)
731         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
732         assert.False(t, result)
733         assert.NotNil(t, err)
734         r.AssertExpectations(t)
735 }
736
737 func TestDelIEKeyDoesntExist(t *testing.T) {
738         _, r, db := setupHaEnv(true)
739         expectedMessage := []interface{}{"DELIE", "key", "data"}
740         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
741         result, err := db.DelIE("key", "data")
742         assert.False(t, result)
743         assert.Nil(t, err)
744         r.AssertExpectations(t)
745 }
746
747 func TestDelIEKeyExists(t *testing.T) {
748         _, r, db := setupHaEnv(true)
749         expectedMessage := []interface{}{"DELIE", "key", "data"}
750         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
751         result, err := db.DelIE("key", "data")
752         assert.True(t, result)
753         assert.Nil(t, err)
754         r.AssertExpectations(t)
755 }
756
757 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
758         _, r, db := setupHaEnv(true)
759         expectedMessage := []interface{}{"DELIE", "key", "data"}
760         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
761         result, err := db.DelIE("key", "data")
762         assert.True(t, result)
763         assert.Nil(t, err)
764         r.AssertExpectations(t)
765 }
766
767 func TestDelIEFailure(t *testing.T) {
768         _, r, db := setupHaEnv(true)
769         expectedMessage := []interface{}{"DELIE", "key", "data"}
770         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
771         result, err := db.DelIE("key", "data")
772         assert.False(t, result)
773         assert.NotNil(t, err)
774         r.AssertExpectations(t)
775 }
776
777 func TestDelIECommandMissing(t *testing.T) {
778         _, r, db := setupHaEnv(false)
779         expectedMessage := []interface{}{"DELIE", "key", "data"}
780         r.AssertNotCalled(t, "Do", expectedMessage)
781         result, err := db.DelIE("key", "data")
782         assert.False(t, result)
783         assert.NotNil(t, err)
784         r.AssertExpectations(t)
785 }
786
787 func TestSAddSuccessfully(t *testing.T) {
788         _, r, db := setupHaEnv(true)
789         expectedKey := "key"
790         expectedData := []interface{}{"data", 2}
791         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
792         assert.Nil(t, db.SAdd("key", "data", 2))
793         r.AssertExpectations(t)
794 }
795
796 func TestSAddFailure(t *testing.T) {
797         _, r, db := setupHaEnv(true)
798         expectedKey := "key"
799         expectedData := []interface{}{"data", 2}
800         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
801         assert.NotNil(t, db.SAdd("key", "data", 2))
802         r.AssertExpectations(t)
803 }
804
805 func TestSRemSuccessfully(t *testing.T) {
806         _, r, db := setupHaEnv(true)
807         expectedKey := "key"
808         expectedData := []interface{}{"data", 2}
809         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
810         assert.Nil(t, db.SRem("key", "data", 2))
811         r.AssertExpectations(t)
812 }
813
814 func TestSRemFailure(t *testing.T) {
815         _, r, db := setupHaEnv(true)
816         expectedKey := "key"
817         expectedData := []interface{}{"data", 2}
818         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
819         assert.NotNil(t, db.SRem("key", "data", 2))
820         r.AssertExpectations(t)
821 }
822
823 func TestSMembersSuccessfully(t *testing.T) {
824         _, r, db := setupHaEnv(true)
825         expectedKey := "key"
826         expectedResult := []string{"member1", "member2"}
827         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
828         result, err := db.SMembers("key")
829         assert.Equal(t, result, expectedResult)
830         assert.Nil(t, err)
831         r.AssertExpectations(t)
832 }
833
834 func TestSMembersFailure(t *testing.T) {
835         _, r, db := setupHaEnv(true)
836         expectedKey := "key"
837         expectedResult := []string{"member1", "member2"}
838         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
839                 errors.New("Some error")))
840         result, err := db.SMembers("key")
841         assert.Equal(t, result, expectedResult)
842         assert.NotNil(t, err)
843         r.AssertExpectations(t)
844 }
845
846 func TestSIsMemberIsMember(t *testing.T) {
847         _, r, db := setupHaEnv(true)
848         expectedKey := "key"
849         expectedData := "data"
850         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
851         result, err := db.SIsMember("key", "data")
852         assert.True(t, result)
853         assert.Nil(t, err)
854         r.AssertExpectations(t)
855 }
856
857 func TestSIsMemberIsNotMember(t *testing.T) {
858         _, r, db := setupHaEnv(true)
859         expectedKey := "key"
860         expectedData := "data"
861         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
862         result, err := db.SIsMember("key", "data")
863         assert.False(t, result)
864         assert.Nil(t, err)
865         r.AssertExpectations(t)
866 }
867
868 func TestSIsMemberFailure(t *testing.T) {
869         _, r, db := setupHaEnv(true)
870         expectedKey := "key"
871         expectedData := "data"
872         r.On("SIsMember", expectedKey, expectedData).
873                 Return(redis.NewBoolResult(false, errors.New("Some error")))
874         result, err := db.SIsMember("key", "data")
875         assert.False(t, result)
876         assert.NotNil(t, err)
877         r.AssertExpectations(t)
878 }
879
880 func TestSCardSuccessfully(t *testing.T) {
881         _, r, db := setupHaEnv(true)
882         expectedKey := "key"
883         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
884         result, err := db.SCard("key")
885         assert.Equal(t, int64(1), result)
886         assert.Nil(t, err)
887         r.AssertExpectations(t)
888 }
889
890 func TestSCardFailure(t *testing.T) {
891         _, r, db := setupHaEnv(true)
892         expectedKey := "key"
893         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
894         result, err := db.SCard("key")
895         assert.Equal(t, int64(1), result)
896         assert.NotNil(t, err)
897         r.AssertExpectations(t)
898 }
899
900 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
901         ps, r, db := setupHaEnv(true)
902         ch := make(chan *redis.Message)
903         msg := redis.Message{
904                 Channel: "{prefix},channel",
905                 Pattern: "pattern",
906                 Payload: "event",
907         }
908         ps.On("Channel").Return(ch)
909         ps.On("Unsubscribe").Return(nil)
910         ps.On("Close").Return(nil)
911         count := 0
912         receivedChannel := ""
913         db.SubscribeChannelDB(func(channel string, payload ...string) {
914                 count++
915                 receivedChannel = channel
916         }, "{prefix},channel")
917         ch <- &msg
918         db.UnsubscribeChannelDB("{prefix},channel")
919         time.Sleep(1 * time.Second)
920         assert.Equal(t, 1, count)
921         assert.Equal(t, "channel", receivedChannel)
922         r.AssertExpectations(t)
923         ps.AssertExpectations(t)
924 }
925
926 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
927         ps, r, db := setupHaEnv(true)
928         ch := make(chan *redis.Message)
929         msg1 := redis.Message{
930                 Channel: "{prefix},channel1",
931                 Pattern: "pattern",
932                 Payload: "event",
933         }
934         msg2 := redis.Message{
935                 Channel: "{prefix},channel2",
936                 Pattern: "pattern",
937                 Payload: "event",
938         }
939         ps.On("Channel").Return(ch)
940         ps.On("Subscribe").Return(nil)
941         ps.On("Unsubscribe").Return(nil)
942         ps.On("Unsubscribe").Return(nil)
943         ps.On("Close").Return(nil)
944         count := 0
945         receivedChannel1 := ""
946         db.SubscribeChannelDB(func(channel string, payload ...string) {
947                 count++
948                 receivedChannel1 = channel
949         }, "{prefix},channel1")
950         ch <- &msg1
951         receivedChannel2 := ""
952         db.SubscribeChannelDB(func(channel string, payload ...string) {
953                 count++
954                 receivedChannel2 = channel
955         }, "{prefix},channel2")
956
957         time.Sleep(1 * time.Second)
958         db.UnsubscribeChannelDB("{prefix},channel1")
959         ch <- &msg2
960         db.UnsubscribeChannelDB("{prefix},channel2")
961         time.Sleep(1 * time.Second)
962         assert.Equal(t, 2, count)
963         assert.Equal(t, "channel1", receivedChannel1)
964         assert.Equal(t, "channel2", receivedChannel2)
965         r.AssertExpectations(t)
966         ps.AssertExpectations(t)
967 }
968
969 func TestSubscribeChannelDBTwoSubscribesWithUnequalPrefixAndUnsubscribes(t *testing.T) {
970         ps, r, db := setupHaEnv(true)
971         ch := make(chan *redis.Message)
972         msg1 := redis.Message{
973                 Channel: "{prefix1},channel",
974                 Pattern: "pattern",
975                 Payload: "event",
976         }
977         msg2 := redis.Message{
978                 Channel: "{prefix2},channel",
979                 Pattern: "pattern",
980                 Payload: "event",
981         }
982         ps.On("Channel").Return(ch)
983         ps.On("Subscribe").Return(nil)
984         ps.On("Unsubscribe").Return(nil)
985         ps.On("Unsubscribe").Return(nil)
986         ps.On("Close").Return(nil)
987         count := 0
988         receivedChannel1 := ""
989         db.SubscribeChannelDB(func(channel string, payload ...string) {
990                 count++
991                 receivedChannel1 = channel
992         }, "{prefix1},channel")
993         ch <- &msg1
994         receivedChannel2 := ""
995         db.SubscribeChannelDB(func(channel string, payload ...string) {
996                 count++
997                 receivedChannel2 = channel
998         }, "{prefix2},channel")
999
1000         time.Sleep(1 * time.Second)
1001         db.UnsubscribeChannelDB("{prefix1},channel")
1002         ch <- &msg2
1003         db.UnsubscribeChannelDB("{prefix2},channel")
1004         time.Sleep(1 * time.Second)
1005         assert.Equal(t, 2, count)
1006         assert.Equal(t, "channel", receivedChannel1)
1007         assert.Equal(t, "channel", receivedChannel2)
1008         r.AssertExpectations(t)
1009         ps.AssertExpectations(t)
1010 }
1011
1012 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
1013         ps, r, db := setupHaEnv(true)
1014         ch := make(chan *redis.Message)
1015         msg := redis.Message{
1016                 Channel: "{prefix},channel",
1017                 Pattern: "pattern",
1018                 Payload: "event",
1019         }
1020         ps.On("Channel").Return(ch)
1021         ps.On("Unsubscribe").Return(nil)
1022         ps.On("Close").Return(nil)
1023         count := 0
1024         receivedChannel := ""
1025
1026         db.SubscribeChannelDB(func(channel string, payload ...string) {
1027                 count++
1028                 receivedChannel = channel
1029         }, "{prefix},channel")
1030         ch <- &msg
1031         db.UnsubscribeChannelDB("{prefix},channel")
1032         time.Sleep(1 * time.Second)
1033
1034         db.SubscribeChannelDB(func(channel string, payload ...string) {
1035                 count++
1036                 receivedChannel = channel
1037         }, "{prefix}", "---", "{prefix},channel")
1038         ch <- &msg
1039         db.UnsubscribeChannelDB("{prefix},channel")
1040
1041         time.Sleep(1 * time.Second)
1042         assert.Equal(t, 2, count)
1043         assert.Equal(t, "channel", receivedChannel)
1044         r.AssertExpectations(t)
1045         ps.AssertExpectations(t)
1046 }
1047
1048 func TestSubscribeChannelDBSubscribeReceivedEventIgnoredIfChannelNameIsUnknown(t *testing.T) {
1049         ps, r, db := setupHaEnv(true)
1050         ch := make(chan *redis.Message)
1051         msg := redis.Message{
1052                 Channel: "missingNsPrefixchannel",
1053                 Pattern: "pattern",
1054                 Payload: "event",
1055         }
1056         ps.On("Channel").Return(ch)
1057         ps.On("Unsubscribe").Return(nil)
1058         ps.On("Close").Return(nil)
1059         count := 0
1060         receivedChannel := ""
1061         db.SubscribeChannelDB(func(channel string, payload ...string) {
1062                 count++
1063                 receivedChannel = channel
1064         }, "{prefix},channel")
1065         ch <- &msg
1066         db.UnsubscribeChannelDB("{prefix},channel")
1067         time.Sleep(1 * time.Second)
1068         assert.Equal(t, 0, count)
1069         assert.Equal(t, "", receivedChannel)
1070         r.AssertExpectations(t)
1071         ps.AssertExpectations(t)
1072 }
1073
1074 func TestPTTLSuccessfully(t *testing.T) {
1075         _, r, db := setupHaEnv(true)
1076         expectedKey := "key"
1077         expectedResult := time.Duration(1)
1078         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1079                 nil))
1080         result, err := db.PTTL("key")
1081         assert.Equal(t, result, expectedResult)
1082         assert.Nil(t, err)
1083         r.AssertExpectations(t)
1084 }
1085
1086 func TestPTTLFailure(t *testing.T) {
1087         _, r, db := setupHaEnv(true)
1088         expectedKey := "key"
1089         expectedResult := time.Duration(1)
1090         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1091                 errors.New("Some error")))
1092         result, err := db.PTTL("key")
1093         assert.Equal(t, result, expectedResult)
1094         assert.NotNil(t, err)
1095         r.AssertExpectations(t)
1096 }
1097
1098 func TestPExpireIESuccessfully(t *testing.T) {
1099         _, r, db := setupHaEnv(true)
1100         expectedKey := "key"
1101         expectedData := "data"
1102         expectedDuration := strconv.FormatInt(int64(10000), 10)
1103
1104         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1105                 Return(redis.NewCmdResult(int64(1), nil))
1106
1107         err := db.PExpireIE("key", "data", 10*time.Second)
1108         assert.Nil(t, err)
1109         r.AssertExpectations(t)
1110 }
1111
1112 func TestPExpireIEFailure(t *testing.T) {
1113         _, r, db := setupHaEnv(true)
1114         expectedKey := "key"
1115         expectedData := "data"
1116         expectedDuration := strconv.FormatInt(int64(10000), 10)
1117
1118         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1119                 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
1120
1121         err := db.PExpireIE("key", "data", 10*time.Second)
1122         assert.NotNil(t, err)
1123         r.AssertExpectations(t)
1124 }
1125
1126 func TestPExpireIELockNotHeld(t *testing.T) {
1127         _, r, db := setupHaEnv(true)
1128         expectedKey := "key"
1129         expectedData := "data"
1130         expectedDuration := strconv.FormatInt(int64(10000), 10)
1131
1132         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1133                 Return(redis.NewCmdResult(int64(0), nil))
1134
1135         err := db.PExpireIE("key", "data", 10*time.Second)
1136         assert.NotNil(t, err)
1137         r.AssertExpectations(t)
1138 }
1139
1140 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
1141         setupVals := setupEnv(
1142                 true,
1143                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "", "", "", "",
1144         )
1145         assert.Equal(t, 1, len(setupVals.rClient))
1146         assert.Equal(t, 1, len(setupVals.db))
1147
1148         expectedKeysAndValues := []interface{}{"key1", "value1"}
1149         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1150         err := setupVals.db[0].MSet("key1", "value1")
1151         assert.Nil(t, err)
1152         setupVals.rClient[0].AssertExpectations(t)
1153 }
1154
1155 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
1156         setupVals := setupEnv(
1157                 true,
1158                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0", "26379", "", "3",
1159         )
1160         assert.Equal(t, 1, len(setupVals.rClient))
1161         assert.Equal(t, 1, len(setupVals.db))
1162
1163         expectedKeysAndValues := []interface{}{"key1", "value1"}
1164         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1165         err := setupVals.db[0].MSet("key1", "value1")
1166         assert.Nil(t, err)
1167         setupVals.rClient[0].AssertExpectations(t)
1168 }
1169
1170 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
1171         setupVals := setupEnv(
1172                 true,
1173                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "", "",
1174                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
1175         )
1176         assert.Equal(t, 2, len(setupVals.rClient))
1177         assert.Equal(t, 2, len(setupVals.db))
1178
1179         expectedKeysAndValues := []interface{}{"key1", "value1"}
1180         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1181         err := setupVals.db[0].MSet("key1", "value1")
1182         assert.Nil(t, err)
1183         setupVals.rClient[0].AssertExpectations(t)
1184
1185         expectedKeysAndValues = []interface{}{"key2", "value2"}
1186         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1187         err = setupVals.db[1].MSet("key2", "value2")
1188         assert.Nil(t, err)
1189         setupVals.rClient[0].AssertExpectations(t)
1190         setupVals.rClient[1].AssertExpectations(t)
1191 }
1192
1193 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1194         setupVals := setupEnv(
1195                 true,
1196                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
1197                 "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1198         )
1199         assert.Equal(t, 2, len(setupVals.rClient))
1200         assert.Equal(t, 2, len(setupVals.db))
1201
1202         expectedKeysAndValues := []interface{}{"key1", "value1"}
1203         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1204         err := setupVals.db[0].MSet("key1", "value1")
1205         assert.Nil(t, err)
1206         setupVals.rClient[0].AssertExpectations(t)
1207
1208         expectedKeysAndValues = []interface{}{"key2", "value2"}
1209         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1210         err = setupVals.db[1].MSet("key2", "value2")
1211         assert.Nil(t, err)
1212         setupVals.rClient[0].AssertExpectations(t)
1213         setupVals.rClient[1].AssertExpectations(t)
1214 }
1215
1216 func TestCompleteConfigIfLessPortsThanAddresses(t *testing.T) {
1217         setupVals := setupEnv(
1218                 true,
1219                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
1220                 "", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1221         )
1222         assert.Equal(t, 2, len(setupVals.rClient))
1223         assert.Equal(t, 2, len(setupVals.db))
1224 }
1225
1226 func TestCompleteConfigIfLessSentinelPortsThanAddresses(t *testing.T) {
1227         setupVals := setupEnv(
1228                 true,
1229                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
1230                 "26379", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1231         )
1232         assert.Equal(t, 2, len(setupVals.rClient))
1233         assert.Equal(t, 2, len(setupVals.db))
1234 }
1235
1236 func TestCompleteConfigIfLessSentinelNamesThanAddresses(t *testing.T) {
1237         setupVals := setupEnv(
1238                 true,
1239                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0",
1240                 "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1241         )
1242         assert.Equal(t, 2, len(setupVals.rClient))
1243         assert.Equal(t, 2, len(setupVals.db))
1244 }
1245
1246 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
1247         _, r, db := setupHaEnv(true)
1248         redisInfo := "# Replication\r\n" +
1249                 "role:master\r\n" +
1250                 "connected_slaves:2\r\n" +
1251                 "min_slaves_good_slaves:2\r\n" +
1252                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1253                 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1254         expInfo := &sdlgoredis.DbInfo{
1255                 Fields: sdlgoredis.DbInfoFields{
1256                         PrimaryRole:         true,
1257                         ConnectedReplicaCnt: 2,
1258                 },
1259         }
1260
1261         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1262         info, err := db.Info()
1263         assert.Nil(t, err)
1264         assert.Equal(t, expInfo, info)
1265         r.AssertExpectations(t)
1266 }
1267
1268 func TestInfoOfPrimaryRedisWithOneReplicaOnlineAndOtherReplicaNotOnlineSuccessfully(t *testing.T) {
1269         _, r, db := setupHaEnv(true)
1270         redisInfo := "# Replication\r\n" +
1271                 "role:master\r\n" +
1272                 "connected_slaves:1\r\n" +
1273                 "min_slaves_good_slaves:2\r\n" +
1274                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1275                 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1276         expInfo := &sdlgoredis.DbInfo{
1277                 Fields: sdlgoredis.DbInfoFields{
1278                         PrimaryRole:         true,
1279                         ConnectedReplicaCnt: 1,
1280                 },
1281         }
1282
1283         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1284         info, err := db.Info()
1285         assert.Nil(t, err)
1286         assert.Equal(t, expInfo, info)
1287         r.AssertExpectations(t)
1288 }
1289
1290 func TestInfoOfStandalonePrimaryRedisSuccessfully(t *testing.T) {
1291         _, r, db := setupHaEnv(true)
1292         redisInfo := "# Replication\r\n" +
1293                 "role:master\r\n" +
1294                 "connected_slaves:0\r\n" +
1295                 "min_slaves_good_slaves:0\r\n"
1296         expInfo := &sdlgoredis.DbInfo{
1297                 Fields: sdlgoredis.DbInfoFields{
1298                         PrimaryRole:         true,
1299                         ConnectedReplicaCnt: 0,
1300                 },
1301         }
1302
1303         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1304         info, err := db.Info()
1305         assert.Nil(t, err)
1306         assert.Equal(t, expInfo, info)
1307         r.AssertExpectations(t)
1308 }
1309
1310 func TestInfoOfStandalonePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1311         _, r, db := setupHaEnv(true)
1312         redisInfo := "# Replication\r\n" +
1313                 "role:master\r\n" +
1314                 "connected_slaves:not-int\r\n" +
1315                 "min_slaves_good_slaves:0\r\n"
1316         expInfo := &sdlgoredis.DbInfo{
1317                 Fields: sdlgoredis.DbInfoFields{
1318                         PrimaryRole:         true,
1319                         ConnectedReplicaCnt: 0,
1320                 },
1321         }
1322
1323         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1324         info, err := db.Info()
1325         assert.Nil(t, err)
1326         assert.Equal(t, expInfo, info)
1327         r.AssertExpectations(t)
1328 }
1329
1330 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1331         _, r, db := setupHaEnv(true)
1332         redisInfo := "!#¤%&?+?´-\r\n"
1333         expInfo := &sdlgoredis.DbInfo{}
1334
1335         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1336         info, err := db.Info()
1337         assert.Nil(t, err)
1338         assert.Equal(t, expInfo, info)
1339         r.AssertExpectations(t)
1340 }
1341
1342 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1343         _, r, db := setupHaEnv(true)
1344         var redisInfo string
1345         expInfo := &sdlgoredis.DbInfo{
1346                 Fields: sdlgoredis.DbInfoFields{
1347                         PrimaryRole: false,
1348                 },
1349         }
1350
1351         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1352         info, err := db.Info()
1353         assert.Nil(t, err)
1354         assert.Equal(t, expInfo, info)
1355         r.AssertExpectations(t)
1356 }
1357
1358 func TestInfoWithSomeStatisticsOfStandalonePrimaryRedis(t *testing.T) {
1359         _, r, db := setupHaEnv(true)
1360         redisInfo := "# Replication\r\n" +
1361                 "role:master\r\n" +
1362                 "connected_slaves:0\r\n" +
1363                 "min_slaves_good_slaves:0\r\n" +
1364                 "# Server\r\n" +
1365                 "uptime_in_days:23\r\n" +
1366                 "# Clients\r\n" +
1367                 "connected_clients:2\r\n" +
1368                 "# Memory\r\n" +
1369                 "used_memory:2093808\r\n" +
1370                 "used_memory_human:2.00M\r\n" +
1371                 "mem_fragmentation_ratio:6.44\r\n" +
1372                 "# Stats\r\n" +
1373                 "total_connections_received:278\r\n" +
1374                 "# CPU\r\n" +
1375                 "used_cpu_sys:1775.254919\r\n" +
1376                 "# Commandstats\r\n" +
1377                 "cmdstat_role:calls=1,usec=3,usec_per_call=3.00\r\n" +
1378                 "# Keyspace\r\n" +
1379                 "db0:keys=4,expires=0,avg_ttl=0"
1380         expInfo := &sdlgoredis.DbInfo{
1381                 Fields: sdlgoredis.DbInfoFields{
1382                         PrimaryRole:         true,
1383                         ConnectedReplicaCnt: 0,
1384                         Server: sdlgoredis.ServerInfoFields{
1385                                 UptimeInDays: 23,
1386                         },
1387                         Clients: sdlgoredis.ClientsInfoFields{
1388                                 ConnectedClients: 2,
1389                         },
1390                         Memory: sdlgoredis.MeroryInfoFields{
1391                                 UsedMemory:            2093808,
1392                                 UsedMemoryHuman:       "2.00M",
1393                                 MemFragmentationRatio: 6.44,
1394                         },
1395                         Stats: sdlgoredis.StatsInfoFields{
1396                                 TotalConnectionsReceived: 278,
1397                         },
1398                         Cpu: sdlgoredis.CpuInfoFields{
1399                                 UsedCpuSys: 1775.254919,
1400                         },
1401                         Commandstats: sdlgoredis.CommandstatsInfoFields{
1402                                 CmdstatRole: sdlgoredis.CommandstatsValues{
1403                                         Calls:       1,
1404                                         Usec:        3,
1405                                         UsecPerCall: 3.00,
1406                                 },
1407                         },
1408                         Keyspace: sdlgoredis.KeyspaceInfoFields{
1409                                 Db: sdlgoredis.KeyspaceValues{
1410                                         Keys: 4,
1411                                 },
1412                         },
1413                 },
1414         }
1415
1416         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1417         info, err := db.Info()
1418         assert.Nil(t, err)
1419         assert.Equal(t, expInfo, info)
1420         r.AssertExpectations(t)
1421 }
1422
1423 func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1424         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1425
1426         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1427         redisReplicasState := newMockRedisSlavesCall()
1428         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1429         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1430         redisSentinelsState := newMockRedisSentinelsCall()
1431         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1432         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1433
1434         expState := newExpDbState(3, nil)
1435         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1436         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1437         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1438         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1439         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1440
1441         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1442         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1443         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1444         ret, err := db.State()
1445         assert.Nil(t, err)
1446         assert.Equal(t, expState.s, *ret)
1447         r.AssertExpectations(t)
1448 }
1449
1450 func TestStateWithTwoSdlClustersContainingPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1451         setupVals := setupEnv(
1452                 true,
1453                 "", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
1454                 "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1455         )
1456         r := setupVals.rClient
1457         s := setupVals.rSentinel
1458         db := setupVals.db
1459
1460         FstRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1461         FstRedisReplicasState := newMockRedisSlavesCall()
1462         FstRedisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1463         FstRedisReplicasState.add("slave", "10.20.30.50", "6379", "up", "slave")
1464         FstRedisSentinelsState := newMockRedisSentinelsCall()
1465         FstRedisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1466         FstRedisSentinelsState.add("10.20.30.50", "26379", "sentinel")
1467
1468         SndRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.60", "6380", "master")
1469         SndRedisReplicasState := newMockRedisSlavesCall()
1470         SndRedisReplicasState.add("slave", "10.20.30.70", "6380", "up", "slave")
1471         SndRedisReplicasState.add("slave", "10.20.30.80", "6380", "up", "slave")
1472         SndRedisSentinelsState := newMockRedisSentinelsCall()
1473         SndRedisSentinelsState.add("10.20.30.70", "26380", "sentinel")
1474         SndRedisSentinelsState.add("10.20.30.80", "26380", "sentinel")
1475
1476         FstExpState := newExpDbState(3, nil)
1477         FstExpState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1478         FstExpState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1479         FstExpState.addReplica("slave", "10.20.30.50", "6379", "up", "slave", nil)
1480         FstExpState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1481         FstExpState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
1482
1483         SndExpState := newExpDbState(3, nil)
1484         SndExpState.addPrimary("master", "10.20.30.60", "6380", "master", nil)
1485         SndExpState.addReplica("slave", "10.20.30.70", "6380", "up", "slave", nil)
1486         SndExpState.addReplica("slave", "10.20.30.80", "6380", "up", "slave", nil)
1487         SndExpState.addSentinel("10.20.30.70", "26380", "sentinel", nil)
1488         SndExpState.addSentinel("10.20.30.80", "26380", "sentinel", nil)
1489
1490         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(FstRedisPrimaryState, nil))
1491         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisReplicasState.resp, nil))
1492         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisSentinelsState.resp, nil))
1493
1494         s[0].On("Master", "dbaasmaster-cluster-1").Return(redis.NewStringStringMapResult(SndRedisPrimaryState, nil))
1495         s[0].On("Slaves", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisReplicasState.resp, nil))
1496         s[0].On("Sentinels", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisSentinelsState.resp, nil))
1497
1498         ret, err := db[0].State()
1499         assert.Nil(t, err)
1500         assert.Equal(t, FstExpState.s, *ret)
1501
1502         ret, err = db[1].State()
1503         assert.Nil(t, err)
1504         assert.Equal(t, SndExpState.s, *ret)
1505         r[0].AssertExpectations(t)
1506 }
1507
1508 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1509         expErr := errors.New("Some error")
1510         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1511
1512         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1513         redisReplicasState := newMockRedisSlavesCall()
1514         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1515         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1516         redisSentinelsState := newMockRedisSentinelsCall()
1517         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1518         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1519
1520         expState := newExpDbState(3, nil)
1521         expState.addPrimary("", "", "", "", expErr)
1522         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1523         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1524         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1525         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1526
1527         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1528         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1529         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1530         ret, err := db.State()
1531         assert.NotNil(t, err)
1532         assert.Equal(t, expState.s, *ret)
1533         r.AssertExpectations(t)
1534 }
1535
1536 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1537         expErr := errors.New("Some error")
1538         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1539
1540         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1541         redisReplicasState := newMockRedisSlavesCall()
1542         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1543         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1544         redisSentinelsState := newMockRedisSentinelsCall()
1545         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1546         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1547
1548         expState := newExpDbState(3, nil)
1549         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1550         expState.addReplica("", "", "", "", "", expErr)
1551         expState.addReplica("", "", "", "", "", expErr)
1552         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1553         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1554
1555         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1556         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1557         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1558         ret, err := db.State()
1559         assert.NotNil(t, err)
1560         assert.Equal(t, expState.s, *ret)
1561         r.AssertExpectations(t)
1562 }
1563
1564 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1565         expErr := errors.New("Some error")
1566         _, r, s, db := setupHaEnvWithSentinels(true, "2")
1567
1568         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1569         redisReplicasState := newMockRedisSlavesCall()
1570         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1571         redisSentinelsState := newMockRedisSentinelsCall()
1572         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1573
1574         expState := newExpDbState(2, nil)
1575         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1576         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1577         expState.addSentinel("", "", "", expErr)
1578
1579         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1580         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1581         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1582         ret, err := db.State()
1583         assert.NotNil(t, err)
1584         assert.Equal(t, expState.s, *ret)
1585         r.AssertExpectations(t)
1586 }
1587
1588 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1589         expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1590         _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1591
1592         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1593         redisReplicasState := newMockRedisSlavesCall()
1594         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1595         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1596         redisSentinelsState := newMockRedisSentinelsCall()
1597         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1598         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1599
1600         expState := newExpDbState(0, expErr)
1601         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1602         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1603         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1604         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1605         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1606
1607         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1608         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1609         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1610         ret, err := db.State()
1611         assert.Equal(t, expErr, err)
1612         assert.Equal(t, expState.s, *ret)
1613         r.AssertExpectations(t)
1614 }
1615
1616 // Test case to test ignoring of a sentinel entry with zero port. Implementation has been
1617 // done because we miss the fix for the Redis Bug #9240.
1618 func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBugRedisSuccessfully(t *testing.T) {
1619         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1620
1621         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1622         redisReplicasState := newMockRedisSlavesCall()
1623         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1624         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1625         redisSentinelsState := newMockRedisSentinelsCall()
1626         redisSentinelsState.add("10.20.30.40", "0", "s_down,sentinel,disconnected")
1627         redisSentinelsState.add("10.20.30.50", "26379", "sentinel")
1628
1629         expState := newExpDbState(3, nil)
1630         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1631         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1632         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1633         expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
1634
1635         s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1636         s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1637         s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1638         ret, err := db.State()
1639         assert.Nil(t, err)
1640         assert.Equal(t, expState.s, *ret)
1641         r.AssertExpectations(t)
1642 }
1643
1644 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1645         _, r, db := setupSingleEnv(true, "1")
1646         redisInfo := "# Replication\r\n" +
1647                 "role:master\r\n" +
1648                 "connected_slaves:0\r\n" +
1649                 "min_slaves_good_slaves:0\r\n"
1650
1651         expState := &sdlgoredis.DbState{
1652                 ConfigNodeCnt: 1,
1653                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1654                         Fields: sdlgoredis.PrimaryDbStateFields{
1655                                 Role:  "master",
1656                                 Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1657                                 Port:  "6379",
1658                                 Flags: "master",
1659                         },
1660                 },
1661         }
1662
1663         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1664         ret, err := db.State()
1665         assert.Nil(t, err)
1666         assert.Equal(t, expState, ret)
1667         r.AssertExpectations(t)
1668 }
1669
1670 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1671         expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1672         _, r, db := setupSingleEnv(true, "no-int")
1673         redisInfo := "# Replication\r\n" +
1674                 "role:master\r\n" +
1675                 "connected_slaves:0\r\n" +
1676                 "min_slaves_good_slaves:0\r\n"
1677
1678         expState := &sdlgoredis.DbState{
1679                 Err:           expErr,
1680                 ConfigNodeCnt: 0,
1681                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1682                         Fields: sdlgoredis.PrimaryDbStateFields{
1683                                 Role:  "master",
1684                                 Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1685                                 Port:  "6379",
1686                                 Flags: "master",
1687                         },
1688                 },
1689         }
1690
1691         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1692         ret, err := db.State()
1693         assert.Equal(t, expErr, err)
1694         assert.Equal(t, expState, ret)
1695         r.AssertExpectations(t)
1696 }
1697
1698 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1699         expErr := errors.New("Some error")
1700         _, r, db := setupSingleEnv(true, "1")
1701         redisInfo := ""
1702         expState := &sdlgoredis.DbState{
1703                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1704                         Err: expErr,
1705                 },
1706         }
1707
1708         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1709         ret, err := db.State()
1710         assert.NotNil(t, err)
1711         assert.Equal(t, expState, ret)
1712         r.AssertExpectations(t)
1713 }
1714
1715 func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1716         _, r, db := setupSingleEnv(true, "1")
1717         redisInfo := "# Replication\r\n" +
1718                 "role:master\r\n" +
1719                 "connected_slaves:0\r\n" +
1720                 "min_slaves_good_slaves:0\r\n" +
1721                 "# Server\r\n" +
1722                 "uptime_in_days:12\r\n"
1723
1724         expStatistics := &sdlgoredis.DbStatistics{
1725                 Stats: []*sdlgoredis.DbStatisticsInfo{
1726                         {
1727                                 IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1728                                 Port:   "6379",
1729                                 Info: &sdlgoredis.DbInfo{
1730                                         Fields: sdlgoredis.DbInfoFields{
1731                                                 PrimaryRole: true,
1732                                                 Server: sdlgoredis.ServerInfoFields{
1733                                                         UptimeInDays: 12,
1734                                                 },
1735                                         },
1736                                 },
1737                         },
1738                 },
1739         }
1740
1741         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1742         ret, err := db.Statistics()
1743         assert.Nil(t, err)
1744         assert.Equal(t, expStatistics, ret)
1745         r.AssertExpectations(t)
1746 }