c95b8afbdc9790bd28cee286e3dd7b1dbf37770b
[ric-plt/sdlgo.git] / internal / sdlgoredis / sdlgoredis_test.go
1 /*
2    Copyright (c) 2019 AT&T Intellectual Property.
3    Copyright (c) 2018-2019 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                 "6376",
193                 "dbaasmaster",
194                 "26376",
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                 "6376", "", "", "", 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(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
255                         s := &sdlgoredis.Sentinel{
256                                 IredisSentinelClient: smock,
257                                 Cfg:                  cfg,
258                         }
259                         return s
260                 },
261         )
262         ret.db = clients
263         return ret
264 }
265
266 func newMockRedisMasterCallResp(role, ip, port, flag string) map[string]string {
267         resp := map[string]string{}
268         if role != "" {
269                 resp["role-reported"] = role
270                 resp["ip"] = ip
271                 resp["port"] = port
272                 resp["flags"] = flag
273         }
274         return resp
275 }
276
277 type mockRedisSlaves struct {
278         resp []interface{}
279 }
280
281 func newMockRedisSlavesCall() *mockRedisSlaves {
282         return new(mockRedisSlaves)
283 }
284
285 func (mrr *mockRedisSlaves) add(role, ip, port, link, flag string) {
286         mrr.resp = append(mrr.resp,
287                 []interface{}{
288                         "role-reported", role,
289                         "ip", ip,
290                         "port", port,
291                         "master-link-status", link,
292                         "flags", flag,
293                 },
294         )
295 }
296
297 type mockRedisSentinels struct {
298         resp []interface{}
299 }
300
301 func newMockRedisSentinelsCall() *mockRedisSentinels {
302         return new(mockRedisSentinels)
303 }
304
305 func (mrs *mockRedisSentinels) add(ip, port, flag string) {
306         mrs.resp = append(mrs.resp,
307                 []interface{}{
308                         "ip", ip,
309                         "port", port,
310                         "flags", flag,
311                 },
312         )
313 }
314
315 type ExpDbState struct {
316         s sdlgoredis.DbState
317 }
318
319 func newExpDbState(nodeCnt int, err error) *ExpDbState {
320         state := new(ExpDbState)
321         state.s.ConfigNodeCnt = nodeCnt
322         state.s.Err = err
323         return state
324 }
325
326 func (edbs *ExpDbState) addPrimary(role, ip, port, flag string, err error) {
327         edbs.s.PrimaryDbState.Err = err
328         edbs.s.PrimaryDbState.Fields = sdlgoredis.PrimaryDbStateFields{
329                 Role:  role,
330                 Ip:    ip,
331                 Port:  port,
332                 Flags: flag,
333         }
334 }
335
336 func (edbs *ExpDbState) addReplica(role, ip, port, link, flag string, err error) {
337         if edbs.s.ReplicasDbState == nil {
338                 edbs.s.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
339                 edbs.s.ReplicasDbState.States = make([]*sdlgoredis.ReplicaDbState, 0)
340         }
341         edbs.s.ReplicasDbState.Err = err
342         if ip != "" || port != "" || link != "" || flag != "" {
343                 edbs.s.ReplicasDbState.States = append(edbs.s.ReplicasDbState.States,
344                         &sdlgoredis.ReplicaDbState{
345                                 Fields: sdlgoredis.ReplicaDbStateFields{
346                                         Role:              role,
347                                         Ip:                ip,
348                                         Port:              port,
349                                         PrimaryLinkStatus: link,
350                                         Flags:             flag,
351                                 },
352                         },
353                 )
354         }
355 }
356
357 func (edbs *ExpDbState) addSentinel(ip, port, flag string, err error) {
358         if edbs.s.SentinelsDbState == nil {
359                 edbs.s.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
360                 edbs.s.SentinelsDbState.States = make([]*sdlgoredis.SentinelDbState, 0)
361         }
362         edbs.s.SentinelsDbState.Err = err
363         if ip != "" || port != "" || flag != "" {
364                 edbs.s.SentinelsDbState.States = append(edbs.s.SentinelsDbState.States,
365                         &sdlgoredis.SentinelDbState{
366                                 Fields: sdlgoredis.SentinelDbStateFields{
367                                         Ip:    ip,
368                                         Port:  port,
369                                         Flags: flag,
370                                 },
371                         },
372                 )
373         }
374 }
375
376 func TestCloseDbSuccessfully(t *testing.T) {
377         _, r, db := setupHaEnv(true)
378         r.On("Close").Return(nil)
379         err := db.CloseDB()
380         assert.Nil(t, err)
381         r.AssertExpectations(t)
382 }
383
384 func TestCloseDbFailure(t *testing.T) {
385         _, r, db := setupHaEnv(true)
386         r.On("Close").Return(errors.New("Some error"))
387         err := db.CloseDB()
388         assert.NotNil(t, err)
389         r.AssertExpectations(t)
390 }
391
392 func TestMSetSuccessfully(t *testing.T) {
393         _, r, db := setupHaEnv(true)
394         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
395         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
396         err := db.MSet("key1", "value1", "key2", 2)
397         assert.Nil(t, err)
398         r.AssertExpectations(t)
399 }
400
401 func TestMSetFailure(t *testing.T) {
402         _, r, db := setupHaEnv(true)
403         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
404         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
405         err := db.MSet("key1", "value1", "key2", 2)
406         assert.NotNil(t, err)
407         r.AssertExpectations(t)
408 }
409
410 func TestMSetMPubSuccessfully(t *testing.T) {
411         _, r, db := setupHaEnv(true)
412         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
413                 "chan1", "event1", "chan2", "event2"}
414         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
415         assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
416                 "key1", "val1", "key2", "val2"))
417         r.AssertExpectations(t)
418 }
419
420 func TestMsetMPubFailure(t *testing.T) {
421         _, r, db := setupHaEnv(true)
422         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
423                 "chan1", "event1", "chan2", "event2"}
424         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
425         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
426                 "key1", "val1", "key2", "val2"))
427         r.AssertExpectations(t)
428 }
429
430 func TestMSetMPubCommandMissing(t *testing.T) {
431         _, r, db := setupHaEnv(false)
432         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
433                 "chan1", "event1", "chan2", "event2"}
434         r.AssertNotCalled(t, "Do", expectedMessage)
435         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
436                 "key1", "val1", "key2", "val2"))
437         r.AssertExpectations(t)
438
439 }
440
441 func TestMGetSuccessfully(t *testing.T) {
442         _, r, db := setupHaEnv(true)
443         expectedKeys := []string{"key1", "key2", "key3"}
444         expectedResult := []interface{}{"val1", 2, nil}
445         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
446         result, err := db.MGet([]string{"key1", "key2", "key3"})
447         assert.Equal(t, result, expectedResult)
448         assert.Nil(t, err)
449         r.AssertExpectations(t)
450 }
451
452 func TestMGetFailure(t *testing.T) {
453         _, r, db := setupHaEnv(true)
454         expectedKeys := []string{"key1", "key2", "key3"}
455         expectedResult := []interface{}{nil}
456         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
457                 errors.New("Some error")))
458         result, err := db.MGet([]string{"key1", "key2", "key3"})
459         assert.Equal(t, result, expectedResult)
460         assert.NotNil(t, err)
461         r.AssertExpectations(t)
462 }
463
464 func TestDelMPubSuccessfully(t *testing.T) {
465         _, r, db := setupHaEnv(true)
466         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
467                 "chan2", "event2"}
468         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
469         assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
470                 []string{"key1", "key2"}))
471         r.AssertExpectations(t)
472 }
473
474 func TestDelMPubFailure(t *testing.T) {
475         _, r, db := setupHaEnv(true)
476         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
477                 "chan2", "event2"}
478         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
479         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
480                 []string{"key1", "key2"}))
481         r.AssertExpectations(t)
482 }
483
484 func TestDelMPubCommandMissing(t *testing.T) {
485         _, r, db := setupHaEnv(false)
486         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
487                 "chan2", "event2"}
488         r.AssertNotCalled(t, "Do", expectedMessage)
489         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
490                 []string{"key1", "key2"}))
491         r.AssertExpectations(t)
492 }
493
494 func TestDelSuccessfully(t *testing.T) {
495         _, r, db := setupHaEnv(true)
496         expectedKeys := []string{"key1", "key2"}
497         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
498         assert.Nil(t, db.Del([]string{"key1", "key2"}))
499         r.AssertExpectations(t)
500 }
501
502 func TestDelFailure(t *testing.T) {
503         _, r, db := setupHaEnv(true)
504         expectedKeys := []string{"key1", "key2"}
505         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
506         assert.NotNil(t, db.Del([]string{"key1", "key2"}))
507         r.AssertExpectations(t)
508 }
509
510 func TestKeysSuccessfully(t *testing.T) {
511         _, r, db := setupHaEnv(true)
512         expectedPattern := "pattern*"
513         expectedResult := []string{"pattern1", "pattern2"}
514         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
515         result, err := db.Keys("pattern*")
516         assert.Equal(t, result, expectedResult)
517         assert.Nil(t, err)
518         r.AssertExpectations(t)
519 }
520
521 func TestKeysFailure(t *testing.T) {
522         _, r, db := setupHaEnv(true)
523         expectedPattern := "pattern*"
524         expectedResult := []string{}
525         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
526                 errors.New("Some error")))
527         _, err := db.Keys("pattern*")
528         assert.NotNil(t, err)
529         r.AssertExpectations(t)
530 }
531
532 func TestSetIEKeyExists(t *testing.T) {
533         _, r, db := setupHaEnv(true)
534         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
535         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
536         result, err := db.SetIE("key", "olddata", "newdata")
537         assert.True(t, result)
538         assert.Nil(t, err)
539         r.AssertExpectations(t)
540 }
541
542 func TestSetIEKeyDoesntExists(t *testing.T) {
543         _, r, db := setupHaEnv(true)
544         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
545         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
546         result, err := db.SetIE("key", "olddata", "newdata")
547         assert.False(t, result)
548         assert.Nil(t, err)
549         r.AssertExpectations(t)
550 }
551
552 func TestSetIEFailure(t *testing.T) {
553         _, r, db := setupHaEnv(true)
554         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
555         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
556         result, err := db.SetIE("key", "olddata", "newdata")
557         assert.False(t, result)
558         assert.NotNil(t, err)
559         r.AssertExpectations(t)
560 }
561
562 func TestSetIECommandMissing(t *testing.T) {
563         _, r, db := setupHaEnv(false)
564         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
565         r.AssertNotCalled(t, "Do", expectedMessage)
566         result, err := db.SetIE("key", "olddata", "newdata")
567         assert.False(t, result)
568         assert.NotNil(t, err)
569         r.AssertExpectations(t)
570 }
571
572 func TestSetIEPubKeyExists(t *testing.T) {
573         _, r, db := setupHaEnv(true)
574         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
575         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
576         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
577         assert.True(t, result)
578         assert.Nil(t, err)
579         r.AssertExpectations(t)
580 }
581
582 func TestSetIEPubKeyDoesntExists(t *testing.T) {
583         _, r, db := setupHaEnv(true)
584         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
585         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
586         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
587         assert.False(t, result)
588         assert.Nil(t, err)
589         r.AssertExpectations(t)
590 }
591
592 func TestSetIEPubFailure(t *testing.T) {
593         _, r, db := setupHaEnv(true)
594         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
595         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
596         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
597         assert.False(t, result)
598         assert.NotNil(t, err)
599         r.AssertExpectations(t)
600 }
601
602 func TestSetIEPubCommandMissing(t *testing.T) {
603         _, r, db := setupHaEnv(false)
604         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
605         r.AssertNotCalled(t, "Do", expectedMessage)
606         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
607         assert.False(t, result)
608         assert.NotNil(t, err)
609         r.AssertExpectations(t)
610 }
611
612 func TestSetNXPubKeyDoesntExist(t *testing.T) {
613         _, r, db := setupHaEnv(true)
614         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
615         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
616         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
617         assert.True(t, result)
618         assert.Nil(t, err)
619         r.AssertExpectations(t)
620 }
621
622 func TestSetNXPubKeyExists(t *testing.T) {
623         _, r, db := setupHaEnv(true)
624         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
625         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
626         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
627         assert.False(t, result)
628         assert.Nil(t, err)
629         r.AssertExpectations(t)
630 }
631
632 func TestSetNXPubFailure(t *testing.T) {
633         _, r, db := setupHaEnv(true)
634         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
635         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
636         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
637         assert.False(t, result)
638         assert.NotNil(t, err)
639         r.AssertExpectations(t)
640 }
641
642 func TestSetNXPubCommandMissing(t *testing.T) {
643         _, r, db := setupHaEnv(false)
644         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
645         r.AssertNotCalled(t, "Do", expectedMessage)
646         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
647         assert.False(t, result)
648         assert.NotNil(t, err)
649         r.AssertExpectations(t)
650 }
651
652 func TestSetNXSuccessfully(t *testing.T) {
653         _, r, db := setupHaEnv(true)
654         expectedKey := "key"
655         expectedData := "data"
656         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
657         result, err := db.SetNX("key", "data", 0)
658         assert.True(t, result)
659         assert.Nil(t, err)
660         r.AssertExpectations(t)
661 }
662
663 func TestSetNXUnsuccessfully(t *testing.T) {
664         _, r, db := setupHaEnv(true)
665         expectedKey := "key"
666         expectedData := "data"
667         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
668         result, err := db.SetNX("key", "data", 0)
669         assert.False(t, result)
670         assert.Nil(t, err)
671         r.AssertExpectations(t)
672 }
673
674 func TestSetNXFailure(t *testing.T) {
675         _, r, db := setupHaEnv(true)
676         expectedKey := "key"
677         expectedData := "data"
678         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
679                 Return(redis.NewBoolResult(false, errors.New("Some error")))
680         result, err := db.SetNX("key", "data", 0)
681         assert.False(t, result)
682         assert.NotNil(t, err)
683         r.AssertExpectations(t)
684 }
685
686 func TestDelIEPubKeyDoesntExist(t *testing.T) {
687         _, r, db := setupHaEnv(true)
688         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
689         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
690         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
691         assert.False(t, result)
692         assert.Nil(t, err)
693         r.AssertExpectations(t)
694 }
695
696 func TestDelIEPubKeyExists(t *testing.T) {
697         _, r, db := setupHaEnv(true)
698         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
699         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
700         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
701         assert.True(t, result)
702         assert.Nil(t, err)
703         r.AssertExpectations(t)
704 }
705
706 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
707         _, r, db := setupHaEnv(true)
708         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
709         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
710         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
711         assert.True(t, result)
712         assert.Nil(t, err)
713         r.AssertExpectations(t)
714 }
715
716 func TestDelIEPubFailure(t *testing.T) {
717         _, r, db := setupHaEnv(true)
718         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
719         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
720         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
721         assert.False(t, result)
722         assert.NotNil(t, err)
723         r.AssertExpectations(t)
724 }
725
726 func TestDelIEPubCommandMissing(t *testing.T) {
727         _, r, db := setupHaEnv(false)
728         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
729         r.AssertNotCalled(t, "Do", expectedMessage)
730         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
731         assert.False(t, result)
732         assert.NotNil(t, err)
733         r.AssertExpectations(t)
734 }
735
736 func TestDelIEKeyDoesntExist(t *testing.T) {
737         _, r, db := setupHaEnv(true)
738         expectedMessage := []interface{}{"DELIE", "key", "data"}
739         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
740         result, err := db.DelIE("key", "data")
741         assert.False(t, result)
742         assert.Nil(t, err)
743         r.AssertExpectations(t)
744 }
745
746 func TestDelIEKeyExists(t *testing.T) {
747         _, r, db := setupHaEnv(true)
748         expectedMessage := []interface{}{"DELIE", "key", "data"}
749         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
750         result, err := db.DelIE("key", "data")
751         assert.True(t, result)
752         assert.Nil(t, err)
753         r.AssertExpectations(t)
754 }
755
756 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
757         _, r, db := setupHaEnv(true)
758         expectedMessage := []interface{}{"DELIE", "key", "data"}
759         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
760         result, err := db.DelIE("key", "data")
761         assert.True(t, result)
762         assert.Nil(t, err)
763         r.AssertExpectations(t)
764 }
765
766 func TestDelIEFailure(t *testing.T) {
767         _, r, db := setupHaEnv(true)
768         expectedMessage := []interface{}{"DELIE", "key", "data"}
769         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
770         result, err := db.DelIE("key", "data")
771         assert.False(t, result)
772         assert.NotNil(t, err)
773         r.AssertExpectations(t)
774 }
775
776 func TestDelIECommandMissing(t *testing.T) {
777         _, r, db := setupHaEnv(false)
778         expectedMessage := []interface{}{"DELIE", "key", "data"}
779         r.AssertNotCalled(t, "Do", expectedMessage)
780         result, err := db.DelIE("key", "data")
781         assert.False(t, result)
782         assert.NotNil(t, err)
783         r.AssertExpectations(t)
784 }
785
786 func TestSAddSuccessfully(t *testing.T) {
787         _, r, db := setupHaEnv(true)
788         expectedKey := "key"
789         expectedData := []interface{}{"data", 2}
790         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
791         assert.Nil(t, db.SAdd("key", "data", 2))
792         r.AssertExpectations(t)
793 }
794
795 func TestSAddFailure(t *testing.T) {
796         _, r, db := setupHaEnv(true)
797         expectedKey := "key"
798         expectedData := []interface{}{"data", 2}
799         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
800         assert.NotNil(t, db.SAdd("key", "data", 2))
801         r.AssertExpectations(t)
802 }
803
804 func TestSRemSuccessfully(t *testing.T) {
805         _, r, db := setupHaEnv(true)
806         expectedKey := "key"
807         expectedData := []interface{}{"data", 2}
808         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
809         assert.Nil(t, db.SRem("key", "data", 2))
810         r.AssertExpectations(t)
811 }
812
813 func TestSRemFailure(t *testing.T) {
814         _, r, db := setupHaEnv(true)
815         expectedKey := "key"
816         expectedData := []interface{}{"data", 2}
817         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
818         assert.NotNil(t, db.SRem("key", "data", 2))
819         r.AssertExpectations(t)
820 }
821
822 func TestSMembersSuccessfully(t *testing.T) {
823         _, r, db := setupHaEnv(true)
824         expectedKey := "key"
825         expectedResult := []string{"member1", "member2"}
826         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
827         result, err := db.SMembers("key")
828         assert.Equal(t, result, expectedResult)
829         assert.Nil(t, err)
830         r.AssertExpectations(t)
831 }
832
833 func TestSMembersFailure(t *testing.T) {
834         _, r, db := setupHaEnv(true)
835         expectedKey := "key"
836         expectedResult := []string{"member1", "member2"}
837         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
838                 errors.New("Some error")))
839         result, err := db.SMembers("key")
840         assert.Equal(t, result, expectedResult)
841         assert.NotNil(t, err)
842         r.AssertExpectations(t)
843 }
844
845 func TestSIsMemberIsMember(t *testing.T) {
846         _, r, db := setupHaEnv(true)
847         expectedKey := "key"
848         expectedData := "data"
849         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
850         result, err := db.SIsMember("key", "data")
851         assert.True(t, result)
852         assert.Nil(t, err)
853         r.AssertExpectations(t)
854 }
855
856 func TestSIsMemberIsNotMember(t *testing.T) {
857         _, r, db := setupHaEnv(true)
858         expectedKey := "key"
859         expectedData := "data"
860         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
861         result, err := db.SIsMember("key", "data")
862         assert.False(t, result)
863         assert.Nil(t, err)
864         r.AssertExpectations(t)
865 }
866
867 func TestSIsMemberFailure(t *testing.T) {
868         _, r, db := setupHaEnv(true)
869         expectedKey := "key"
870         expectedData := "data"
871         r.On("SIsMember", expectedKey, expectedData).
872                 Return(redis.NewBoolResult(false, errors.New("Some error")))
873         result, err := db.SIsMember("key", "data")
874         assert.False(t, result)
875         assert.NotNil(t, err)
876         r.AssertExpectations(t)
877 }
878
879 func TestSCardSuccessfully(t *testing.T) {
880         _, r, db := setupHaEnv(true)
881         expectedKey := "key"
882         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
883         result, err := db.SCard("key")
884         assert.Equal(t, int64(1), result)
885         assert.Nil(t, err)
886         r.AssertExpectations(t)
887 }
888
889 func TestSCardFailure(t *testing.T) {
890         _, r, db := setupHaEnv(true)
891         expectedKey := "key"
892         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
893         result, err := db.SCard("key")
894         assert.Equal(t, int64(1), result)
895         assert.NotNil(t, err)
896         r.AssertExpectations(t)
897 }
898
899 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
900         ps, r, db := setupHaEnv(true)
901         ch := make(chan *redis.Message)
902         msg := redis.Message{
903                 Channel: "{prefix},channel",
904                 Pattern: "pattern",
905                 Payload: "event",
906         }
907         ps.On("Channel").Return(ch)
908         ps.On("Unsubscribe").Return(nil)
909         ps.On("Close").Return(nil)
910         count := 0
911         receivedChannel := ""
912         db.SubscribeChannelDB(func(channel string, payload ...string) {
913                 count++
914                 receivedChannel = channel
915         }, "{prefix},channel")
916         ch <- &msg
917         db.UnsubscribeChannelDB("{prefix},channel")
918         time.Sleep(1 * time.Second)
919         assert.Equal(t, 1, count)
920         assert.Equal(t, "channel", receivedChannel)
921         r.AssertExpectations(t)
922         ps.AssertExpectations(t)
923 }
924
925 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
926         ps, r, db := setupHaEnv(true)
927         ch := make(chan *redis.Message)
928         msg1 := redis.Message{
929                 Channel: "{prefix},channel1",
930                 Pattern: "pattern",
931                 Payload: "event",
932         }
933         msg2 := redis.Message{
934                 Channel: "{prefix},channel2",
935                 Pattern: "pattern",
936                 Payload: "event",
937         }
938         ps.On("Channel").Return(ch)
939         ps.On("Subscribe").Return(nil)
940         ps.On("Unsubscribe").Return(nil)
941         ps.On("Unsubscribe").Return(nil)
942         ps.On("Close").Return(nil)
943         count := 0
944         receivedChannel1 := ""
945         db.SubscribeChannelDB(func(channel string, payload ...string) {
946                 count++
947                 receivedChannel1 = channel
948         }, "{prefix},channel1")
949         ch <- &msg1
950         receivedChannel2 := ""
951         db.SubscribeChannelDB(func(channel string, payload ...string) {
952                 count++
953                 receivedChannel2 = channel
954         }, "{prefix},channel2")
955
956         time.Sleep(1 * time.Second)
957         db.UnsubscribeChannelDB("{prefix},channel1")
958         ch <- &msg2
959         db.UnsubscribeChannelDB("{prefix},channel2")
960         time.Sleep(1 * time.Second)
961         assert.Equal(t, 2, count)
962         assert.Equal(t, "channel1", receivedChannel1)
963         assert.Equal(t, "channel2", receivedChannel2)
964         r.AssertExpectations(t)
965         ps.AssertExpectations(t)
966 }
967
968 func TestSubscribeChannelDBTwoSubscribesWithUnequalPrefixAndUnsubscribes(t *testing.T) {
969         ps, r, db := setupHaEnv(true)
970         ch := make(chan *redis.Message)
971         msg1 := redis.Message{
972                 Channel: "{prefix1},channel",
973                 Pattern: "pattern",
974                 Payload: "event",
975         }
976         msg2 := redis.Message{
977                 Channel: "{prefix2},channel",
978                 Pattern: "pattern",
979                 Payload: "event",
980         }
981         ps.On("Channel").Return(ch)
982         ps.On("Subscribe").Return(nil)
983         ps.On("Unsubscribe").Return(nil)
984         ps.On("Unsubscribe").Return(nil)
985         ps.On("Close").Return(nil)
986         count := 0
987         receivedChannel1 := ""
988         db.SubscribeChannelDB(func(channel string, payload ...string) {
989                 count++
990                 receivedChannel1 = channel
991         }, "{prefix1},channel")
992         ch <- &msg1
993         receivedChannel2 := ""
994         db.SubscribeChannelDB(func(channel string, payload ...string) {
995                 count++
996                 receivedChannel2 = channel
997         }, "{prefix2},channel")
998
999         time.Sleep(1 * time.Second)
1000         db.UnsubscribeChannelDB("{prefix1},channel")
1001         ch <- &msg2
1002         db.UnsubscribeChannelDB("{prefix2},channel")
1003         time.Sleep(1 * time.Second)
1004         assert.Equal(t, 2, count)
1005         assert.Equal(t, "channel", receivedChannel1)
1006         assert.Equal(t, "channel", receivedChannel2)
1007         r.AssertExpectations(t)
1008         ps.AssertExpectations(t)
1009 }
1010
1011 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
1012         ps, r, db := setupHaEnv(true)
1013         ch := make(chan *redis.Message)
1014         msg := redis.Message{
1015                 Channel: "{prefix},channel",
1016                 Pattern: "pattern",
1017                 Payload: "event",
1018         }
1019         ps.On("Channel").Return(ch)
1020         ps.On("Unsubscribe").Return(nil)
1021         ps.On("Close").Return(nil)
1022         count := 0
1023         receivedChannel := ""
1024
1025         db.SubscribeChannelDB(func(channel string, payload ...string) {
1026                 count++
1027                 receivedChannel = channel
1028         }, "{prefix},channel")
1029         ch <- &msg
1030         db.UnsubscribeChannelDB("{prefix},channel")
1031         time.Sleep(1 * time.Second)
1032
1033         db.SubscribeChannelDB(func(channel string, payload ...string) {
1034                 count++
1035                 receivedChannel = channel
1036         }, "{prefix}", "---", "{prefix},channel")
1037         ch <- &msg
1038         db.UnsubscribeChannelDB("{prefix},channel")
1039
1040         time.Sleep(1 * time.Second)
1041         assert.Equal(t, 2, count)
1042         assert.Equal(t, "channel", receivedChannel)
1043         r.AssertExpectations(t)
1044         ps.AssertExpectations(t)
1045 }
1046
1047 func TestSubscribeChannelDBSubscribeReceivedEventIgnoredIfChannelNameIsUnknown(t *testing.T) {
1048         ps, r, db := setupHaEnv(true)
1049         ch := make(chan *redis.Message)
1050         msg := redis.Message{
1051                 Channel: "missingNsPrefixchannel",
1052                 Pattern: "pattern",
1053                 Payload: "event",
1054         }
1055         ps.On("Channel").Return(ch)
1056         ps.On("Unsubscribe").Return(nil)
1057         ps.On("Close").Return(nil)
1058         count := 0
1059         receivedChannel := ""
1060         db.SubscribeChannelDB(func(channel string, payload ...string) {
1061                 count++
1062                 receivedChannel = channel
1063         }, "{prefix},channel")
1064         ch <- &msg
1065         db.UnsubscribeChannelDB("{prefix},channel")
1066         time.Sleep(1 * time.Second)
1067         assert.Equal(t, 0, count)
1068         assert.Equal(t, "", receivedChannel)
1069         r.AssertExpectations(t)
1070         ps.AssertExpectations(t)
1071 }
1072
1073 func TestPTTLSuccessfully(t *testing.T) {
1074         _, r, db := setupHaEnv(true)
1075         expectedKey := "key"
1076         expectedResult := time.Duration(1)
1077         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1078                 nil))
1079         result, err := db.PTTL("key")
1080         assert.Equal(t, result, expectedResult)
1081         assert.Nil(t, err)
1082         r.AssertExpectations(t)
1083 }
1084
1085 func TestPTTLFailure(t *testing.T) {
1086         _, r, db := setupHaEnv(true)
1087         expectedKey := "key"
1088         expectedResult := time.Duration(1)
1089         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1090                 errors.New("Some error")))
1091         result, err := db.PTTL("key")
1092         assert.Equal(t, result, expectedResult)
1093         assert.NotNil(t, err)
1094         r.AssertExpectations(t)
1095 }
1096
1097 func TestPExpireIESuccessfully(t *testing.T) {
1098         _, r, db := setupHaEnv(true)
1099         expectedKey := "key"
1100         expectedData := "data"
1101         expectedDuration := strconv.FormatInt(int64(10000), 10)
1102
1103         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1104                 Return(redis.NewCmdResult(int64(1), nil))
1105
1106         err := db.PExpireIE("key", "data", 10*time.Second)
1107         assert.Nil(t, err)
1108         r.AssertExpectations(t)
1109 }
1110
1111 func TestPExpireIEFailure(t *testing.T) {
1112         _, r, db := setupHaEnv(true)
1113         expectedKey := "key"
1114         expectedData := "data"
1115         expectedDuration := strconv.FormatInt(int64(10000), 10)
1116
1117         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1118                 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
1119
1120         err := db.PExpireIE("key", "data", 10*time.Second)
1121         assert.NotNil(t, err)
1122         r.AssertExpectations(t)
1123 }
1124
1125 func TestPExpireIELockNotHeld(t *testing.T) {
1126         _, r, db := setupHaEnv(true)
1127         expectedKey := "key"
1128         expectedData := "data"
1129         expectedDuration := strconv.FormatInt(int64(10000), 10)
1130
1131         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1132                 Return(redis.NewCmdResult(int64(0), nil))
1133
1134         err := db.PExpireIE("key", "data", 10*time.Second)
1135         assert.NotNil(t, err)
1136         r.AssertExpectations(t)
1137 }
1138
1139 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
1140         setupVals := setupEnv(
1141                 true,
1142                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
1143         )
1144         assert.Equal(t, 1, len(setupVals.rClient))
1145         assert.Equal(t, 1, len(setupVals.db))
1146
1147         expectedKeysAndValues := []interface{}{"key1", "value1"}
1148         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1149         err := setupVals.db[0].MSet("key1", "value1")
1150         assert.Nil(t, err)
1151         setupVals.rClient[0].AssertExpectations(t)
1152 }
1153
1154 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
1155         setupVals := setupEnv(
1156                 true,
1157                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
1158         )
1159         assert.Equal(t, 1, len(setupVals.rClient))
1160         assert.Equal(t, 1, len(setupVals.db))
1161
1162         expectedKeysAndValues := []interface{}{"key1", "value1"}
1163         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1164         err := setupVals.db[0].MSet("key1", "value1")
1165         assert.Nil(t, err)
1166         setupVals.rClient[0].AssertExpectations(t)
1167 }
1168
1169 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
1170         setupVals := setupEnv(
1171                 true,
1172                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
1173                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
1174         )
1175         assert.Equal(t, 2, len(setupVals.rClient))
1176         assert.Equal(t, 2, len(setupVals.db))
1177
1178         expectedKeysAndValues := []interface{}{"key1", "value1"}
1179         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1180         err := setupVals.db[0].MSet("key1", "value1")
1181         assert.Nil(t, err)
1182         setupVals.rClient[0].AssertExpectations(t)
1183
1184         expectedKeysAndValues = []interface{}{"key2", "value2"}
1185         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1186         err = setupVals.db[1].MSet("key2", "value2")
1187         assert.Nil(t, err)
1188         setupVals.rClient[0].AssertExpectations(t)
1189         setupVals.rClient[1].AssertExpectations(t)
1190 }
1191
1192 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1193         setupVals := setupEnv(
1194                 true,
1195                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
1196                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1197         )
1198         assert.Equal(t, 2, len(setupVals.rClient))
1199         assert.Equal(t, 2, len(setupVals.db))
1200
1201         expectedKeysAndValues := []interface{}{"key1", "value1"}
1202         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1203         err := setupVals.db[0].MSet("key1", "value1")
1204         assert.Nil(t, err)
1205         setupVals.rClient[0].AssertExpectations(t)
1206
1207         expectedKeysAndValues = []interface{}{"key2", "value2"}
1208         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1209         err = setupVals.db[1].MSet("key2", "value2")
1210         assert.Nil(t, err)
1211         setupVals.rClient[0].AssertExpectations(t)
1212         setupVals.rClient[1].AssertExpectations(t)
1213 }
1214
1215 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
1216         _, r, db := setupHaEnv(true)
1217         redisInfo := "# Replication\r\n" +
1218                 "role:master\r\n" +
1219                 "connected_slaves:2\r\n" +
1220                 "min_slaves_good_slaves:2\r\n" +
1221                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1222                 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1223         expInfo := &sdlgoredis.DbInfo{
1224                 Fields: sdlgoredis.DbInfoFields{
1225                         PrimaryRole:         true,
1226                         ConnectedReplicaCnt: 2,
1227                 },
1228         }
1229
1230         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1231         info, err := db.Info()
1232         assert.Nil(t, err)
1233         assert.Equal(t, expInfo, info)
1234         r.AssertExpectations(t)
1235 }
1236
1237 func TestInfoOfPrimaryRedisWithOneReplicaOnlineAndOtherReplicaNotOnlineSuccessfully(t *testing.T) {
1238         _, r, db := setupHaEnv(true)
1239         redisInfo := "# Replication\r\n" +
1240                 "role:master\r\n" +
1241                 "connected_slaves:1\r\n" +
1242                 "min_slaves_good_slaves:2\r\n" +
1243                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1244                 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1245         expInfo := &sdlgoredis.DbInfo{
1246                 Fields: sdlgoredis.DbInfoFields{
1247                         PrimaryRole:         true,
1248                         ConnectedReplicaCnt: 1,
1249                 },
1250         }
1251
1252         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1253         info, err := db.Info()
1254         assert.Nil(t, err)
1255         assert.Equal(t, expInfo, info)
1256         r.AssertExpectations(t)
1257 }
1258
1259 func TestInfoOfStandalonePrimaryRedisSuccessfully(t *testing.T) {
1260         _, r, db := setupHaEnv(true)
1261         redisInfo := "# Replication\r\n" +
1262                 "role:master\r\n" +
1263                 "connected_slaves:0\r\n" +
1264                 "min_slaves_good_slaves:0\r\n"
1265         expInfo := &sdlgoredis.DbInfo{
1266                 Fields: sdlgoredis.DbInfoFields{
1267                         PrimaryRole:         true,
1268                         ConnectedReplicaCnt: 0,
1269                 },
1270         }
1271
1272         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1273         info, err := db.Info()
1274         assert.Nil(t, err)
1275         assert.Equal(t, expInfo, info)
1276         r.AssertExpectations(t)
1277 }
1278
1279 func TestInfoOfStandalonePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1280         _, r, db := setupHaEnv(true)
1281         redisInfo := "# Replication\r\n" +
1282                 "role:master\r\n" +
1283                 "connected_slaves:not-int\r\n" +
1284                 "min_slaves_good_slaves:0\r\n"
1285         expInfo := &sdlgoredis.DbInfo{
1286                 Fields: sdlgoredis.DbInfoFields{
1287                         PrimaryRole:         true,
1288                         ConnectedReplicaCnt: 0,
1289                 },
1290         }
1291
1292         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1293         info, err := db.Info()
1294         assert.Nil(t, err)
1295         assert.Equal(t, expInfo, info)
1296         r.AssertExpectations(t)
1297 }
1298
1299 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1300         _, r, db := setupHaEnv(true)
1301         redisInfo := "!#¤%&?+?´-\r\n"
1302         expInfo := &sdlgoredis.DbInfo{}
1303
1304         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1305         info, err := db.Info()
1306         assert.Nil(t, err)
1307         assert.Equal(t, expInfo, info)
1308         r.AssertExpectations(t)
1309 }
1310
1311 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1312         _, r, db := setupHaEnv(true)
1313         var redisInfo string
1314         expInfo := &sdlgoredis.DbInfo{
1315                 Fields: sdlgoredis.DbInfoFields{
1316                         PrimaryRole: false,
1317                 },
1318         }
1319
1320         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1321         info, err := db.Info()
1322         assert.Nil(t, err)
1323         assert.Equal(t, expInfo, info)
1324         r.AssertExpectations(t)
1325 }
1326
1327 func TestInfoWithSomeStatisticsOfStandalonePrimaryRedis(t *testing.T) {
1328         _, r, db := setupHaEnv(true)
1329         redisInfo := "# Replication\r\n" +
1330                 "role:master\r\n" +
1331                 "connected_slaves:0\r\n" +
1332                 "min_slaves_good_slaves:0\r\n" +
1333                 "# Server\r\n" +
1334                 "uptime_in_days:23\r\n" +
1335                 "# Clients\r\n" +
1336                 "connected_clients:2\r\n" +
1337                 "# Memory\r\n" +
1338                 "used_memory:2093808\r\n" +
1339                 "used_memory_human:2.00M\r\n" +
1340                 "mem_fragmentation_ratio:6.44\r\n" +
1341                 "# Stats\r\n" +
1342                 "total_connections_received:278\r\n" +
1343                 "# CPU\r\n" +
1344                 "used_cpu_sys:1775.254919\r\n" +
1345                 "# Commandstats\r\n" +
1346                 "cmdstat_role:calls=1,usec=3,usec_per_call=3.00\r\n" +
1347                 "# Keyspace\r\n" +
1348                 "db0:keys=4,expires=0,avg_ttl=0"
1349         expInfo := &sdlgoredis.DbInfo{
1350                 Fields: sdlgoredis.DbInfoFields{
1351                         PrimaryRole:         true,
1352                         ConnectedReplicaCnt: 0,
1353                         Server: sdlgoredis.ServerInfoFields{
1354                                 UptimeInDays: 23,
1355                         },
1356                         Clients: sdlgoredis.ClientsInfoFields{
1357                                 ConnectedClients: 2,
1358                         },
1359                         Memory: sdlgoredis.MeroryInfoFields{
1360                                 UsedMemory:            2093808,
1361                                 UsedMemoryHuman:       "2.00M",
1362                                 MemFragmentationRatio: 6.44,
1363                         },
1364                         Stats: sdlgoredis.StatsInfoFields{
1365                                 TotalConnectionsReceived: 278,
1366                         },
1367                         Cpu: sdlgoredis.CpuInfoFields{
1368                                 UsedCpuSys: 1775.254919,
1369                         },
1370                         Commandstats: sdlgoredis.CommandstatsInfoFields{
1371                                 CmdstatRole: sdlgoredis.CommandstatsValues{
1372                                         Calls:       1,
1373                                         Usec:        3,
1374                                         UsecPerCall: 3.00,
1375                                 },
1376                         },
1377                         Keyspace: sdlgoredis.KeyspaceInfoFields{
1378                                 Db: sdlgoredis.KeyspaceValues{
1379                                         Keys: 4,
1380                                 },
1381                         },
1382                 },
1383         }
1384
1385         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1386         info, err := db.Info()
1387         assert.Nil(t, err)
1388         assert.Equal(t, expInfo, info)
1389         r.AssertExpectations(t)
1390 }
1391
1392 func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1393         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1394
1395         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1396         redisReplicasState := newMockRedisSlavesCall()
1397         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1398         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1399         redisSentinelsState := newMockRedisSentinelsCall()
1400         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1401         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1402
1403         expState := newExpDbState(3, nil)
1404         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1405         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1406         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1407         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1408         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1409
1410         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1411         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1412         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1413         ret, err := db.State()
1414         assert.Nil(t, err)
1415         assert.Equal(t, expState.s, *ret)
1416         r.AssertExpectations(t)
1417 }
1418
1419 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1420         expErr := errors.New("Some error")
1421         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1422
1423         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1424         redisReplicasState := newMockRedisSlavesCall()
1425         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1426         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1427         redisSentinelsState := newMockRedisSentinelsCall()
1428         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1429         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1430
1431         expState := newExpDbState(3, nil)
1432         expState.addPrimary("", "", "", "", expErr)
1433         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1434         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1435         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1436         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1437
1438         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1439         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1440         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1441         ret, err := db.State()
1442         assert.NotNil(t, err)
1443         assert.Equal(t, expState.s, *ret)
1444         r.AssertExpectations(t)
1445 }
1446
1447 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1448         expErr := errors.New("Some error")
1449         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1450
1451         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1452         redisReplicasState := newMockRedisSlavesCall()
1453         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1454         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1455         redisSentinelsState := newMockRedisSentinelsCall()
1456         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1457         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1458
1459         expState := newExpDbState(3, nil)
1460         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1461         expState.addReplica("", "", "", "", "", expErr)
1462         expState.addReplica("", "", "", "", "", expErr)
1463         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1464         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1465
1466         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1467         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1468         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1469         ret, err := db.State()
1470         assert.NotNil(t, err)
1471         assert.Equal(t, expState.s, *ret)
1472         r.AssertExpectations(t)
1473 }
1474
1475 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1476         expErr := errors.New("Some error")
1477         _, r, s, db := setupHaEnvWithSentinels(true, "2")
1478
1479         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1480         redisReplicasState := newMockRedisSlavesCall()
1481         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1482         redisSentinelsState := newMockRedisSentinelsCall()
1483         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1484
1485         expState := newExpDbState(2, nil)
1486         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1487         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1488         expState.addSentinel("", "", "", expErr)
1489
1490         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1491         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1492         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1493         ret, err := db.State()
1494         assert.NotNil(t, err)
1495         assert.Equal(t, expState.s, *ret)
1496         r.AssertExpectations(t)
1497 }
1498
1499 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1500         expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1501         _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1502
1503         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1504         redisReplicasState := newMockRedisSlavesCall()
1505         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1506         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1507         redisSentinelsState := newMockRedisSentinelsCall()
1508         redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1509         redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1510
1511         expState := newExpDbState(0, expErr)
1512         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1513         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1514         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1515         expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1516         expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1517
1518         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1519         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1520         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1521         ret, err := db.State()
1522         assert.Equal(t, expErr, err)
1523         assert.Equal(t, expState.s, *ret)
1524         r.AssertExpectations(t)
1525 }
1526
1527 // Test case to test ignoring of a sentinel entry with zero port. Implementation has been
1528 // done because we miss the fix for the Redis Bug #9240.
1529 func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBugRedisSuccessfully(t *testing.T) {
1530         _, r, s, db := setupHaEnvWithSentinels(true, "3")
1531
1532         redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1533         redisReplicasState := newMockRedisSlavesCall()
1534         redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1535         redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1536         redisSentinelsState := newMockRedisSentinelsCall()
1537         redisSentinelsState.add("10.20.30.40", "0", "s_down,sentinel,disconnected")
1538         redisSentinelsState.add("10.20.30.50", "26379", "sentinel")
1539
1540         expState := newExpDbState(3, nil)
1541         expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1542         expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1543         expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1544         expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
1545
1546         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1547         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1548         s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1549         ret, err := db.State()
1550         assert.Nil(t, err)
1551         assert.Equal(t, expState.s, *ret)
1552         r.AssertExpectations(t)
1553 }
1554
1555 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1556         _, r, db := setupSingleEnv(true, "1")
1557         redisInfo := "# Replication\r\n" +
1558                 "role:master\r\n" +
1559                 "connected_slaves:0\r\n" +
1560                 "min_slaves_good_slaves:0\r\n"
1561
1562         expState := &sdlgoredis.DbState{
1563                 ConfigNodeCnt: 1,
1564                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1565                         Fields: sdlgoredis.PrimaryDbStateFields{
1566                                 Role:  "master",
1567                                 Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1568                                 Port:  "6376",
1569                                 Flags: "master",
1570                         },
1571                 },
1572         }
1573
1574         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1575         ret, err := db.State()
1576         assert.Nil(t, err)
1577         assert.Equal(t, expState, ret)
1578         r.AssertExpectations(t)
1579 }
1580
1581 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1582         expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1583         _, r, db := setupSingleEnv(true, "no-int")
1584         redisInfo := "# Replication\r\n" +
1585                 "role:master\r\n" +
1586                 "connected_slaves:0\r\n" +
1587                 "min_slaves_good_slaves:0\r\n"
1588
1589         expState := &sdlgoredis.DbState{
1590                 Err:           expErr,
1591                 ConfigNodeCnt: 0,
1592                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1593                         Fields: sdlgoredis.PrimaryDbStateFields{
1594                                 Role:  "master",
1595                                 Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1596                                 Port:  "6376",
1597                                 Flags: "master",
1598                         },
1599                 },
1600         }
1601
1602         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1603         ret, err := db.State()
1604         assert.Equal(t, expErr, err)
1605         assert.Equal(t, expState, ret)
1606         r.AssertExpectations(t)
1607 }
1608
1609 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1610         expErr := errors.New("Some error")
1611         _, r, db := setupSingleEnv(true, "1")
1612         redisInfo := ""
1613         expState := &sdlgoredis.DbState{
1614                 PrimaryDbState: sdlgoredis.PrimaryDbState{
1615                         Err: expErr,
1616                 },
1617         }
1618
1619         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1620         ret, err := db.State()
1621         assert.NotNil(t, err)
1622         assert.Equal(t, expState, ret)
1623         r.AssertExpectations(t)
1624 }
1625
1626 func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1627         _, r, db := setupSingleEnv(true, "1")
1628         redisInfo := "# Replication\r\n" +
1629                 "role:master\r\n" +
1630                 "connected_slaves:0\r\n" +
1631                 "min_slaves_good_slaves:0\r\n" +
1632                 "# Server\r\n" +
1633                 "uptime_in_days:12\r\n"
1634
1635         expStatistics := &sdlgoredis.DbStatistics{
1636                 Stats: []*sdlgoredis.DbStatisticsInfo{
1637                         {
1638                                 IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1639                                 Port:   "6376",
1640                                 Info: &sdlgoredis.DbInfo{
1641                                         Fields: sdlgoredis.DbInfoFields{
1642                                                 PrimaryRole: true,
1643                                                 Server: sdlgoredis.ServerInfoFields{
1644                                                         UptimeInDays: 12,
1645                                                 },
1646                                         },
1647                                 },
1648                         },
1649                 },
1650         }
1651
1652         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1653         ret, err := db.Statistics()
1654         assert.Nil(t, err)
1655         assert.Equal(t, expStatistics, ret)
1656         r.AssertExpectations(t)
1657 }