Implement SDL CLI 'healthcheck' -command
[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         "errors"
27         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
28         "github.com/go-redis/redis/v7"
29         "github.com/stretchr/testify/assert"
30         "github.com/stretchr/testify/mock"
31         "strconv"
32         "testing"
33         "time"
34 )
35
36 type clientMock struct {
37         mock.Mock
38 }
39
40 type pubSubMock struct {
41         mock.Mock
42 }
43
44 type MockOS struct {
45         mock.Mock
46 }
47
48 func (m *pubSubMock) Channel() <-chan *redis.Message {
49         return m.Called().Get(0).(chan *redis.Message)
50 }
51
52 func (m *pubSubMock) Subscribe(channels ...string) error {
53         return m.Called().Error(0)
54 }
55
56 func (m *pubSubMock) Unsubscribe(channels ...string) error {
57         return m.Called().Error(0)
58 }
59
60 func (m *pubSubMock) Close() error {
61         return m.Called().Error(0)
62 }
63
64 func (m *clientMock) Command() *redis.CommandsInfoCmd {
65         return m.Called().Get(0).(*redis.CommandsInfoCmd)
66 }
67
68 func (m *clientMock) Close() error {
69         return m.Called().Error(0)
70 }
71
72 func (m *clientMock) Subscribe(channels ...string) *redis.PubSub {
73         return m.Called(channels).Get(0).(*redis.PubSub)
74 }
75
76 func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
77         return m.Called(pairs).Get(0).(*redis.StatusCmd)
78 }
79
80 func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
81         return m.Called(args).Get(0).(*redis.Cmd)
82 }
83
84 func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
85         return m.Called(keys).Get(0).(*redis.SliceCmd)
86 }
87
88 func (m *clientMock) Del(keys ...string) *redis.IntCmd {
89         return m.Called(keys).Get(0).(*redis.IntCmd)
90 }
91
92 func (m *clientMock) Keys(pattern string) *redis.StringSliceCmd {
93         return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
94 }
95
96 func (m *clientMock) SetNX(key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
97         return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
98 }
99
100 func (m *clientMock) SAdd(key string, members ...interface{}) *redis.IntCmd {
101         return m.Called(key, members).Get(0).(*redis.IntCmd)
102 }
103
104 func (m *clientMock) SRem(key string, members ...interface{}) *redis.IntCmd {
105         return m.Called(key, members).Get(0).(*redis.IntCmd)
106 }
107
108 func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
109         return m.Called(key).Get(0).(*redis.StringSliceCmd)
110 }
111
112 func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
113         return m.Called(key, member).Get(0).(*redis.BoolCmd)
114 }
115
116 func (m *clientMock) SCard(key string) *redis.IntCmd {
117         return m.Called(key).Get(0).(*redis.IntCmd)
118 }
119
120 func (m *clientMock) PTTL(key string) *redis.DurationCmd {
121         return m.Called(key).Get(0).(*redis.DurationCmd)
122 }
123
124 func (m *clientMock) Eval(script string, keys []string, args ...interface{}) *redis.Cmd {
125         return m.Called(script, keys).Get(0).(*redis.Cmd)
126 }
127
128 func (m *clientMock) EvalSha(sha1 string, keys []string, args ...interface{}) *redis.Cmd {
129         return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
130 }
131
132 func (m *clientMock) ScriptExists(scripts ...string) *redis.BoolSliceCmd {
133         return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
134 }
135
136 func (m *clientMock) ScriptLoad(script string) *redis.StringCmd {
137         return m.Called(script).Get(0).(*redis.StringCmd)
138 }
139
140 func (m *clientMock) Info(section ...string) *redis.StringCmd {
141         return m.Called(section).Get(0).(*redis.StringCmd)
142 }
143
144 type MockRedisSentinel struct {
145         mock.Mock
146 }
147
148 func (m *MockRedisSentinel) Master(name string) *redis.StringStringMapCmd {
149         a := m.Called(name)
150         return a.Get(0).(*redis.StringStringMapCmd)
151 }
152 func (m *MockRedisSentinel) Slaves(name string) *redis.SliceCmd {
153         a := m.Called(name)
154         return a.Get(0).(*redis.SliceCmd)
155 }
156
157 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
158         mock := new(pubSubMock)
159         return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
160                 return mock
161         }
162 }
163
164 func (m *MockOS) Getenv(key string, defValue string) string {
165         a := m.Called(key, defValue)
166         return a.String(0)
167 }
168
169 type setupEv struct {
170         pubSubMock []*pubSubMock
171         rClient    []*clientMock
172         rSentinel  []*MockRedisSentinel
173         db         []*sdlgoredis.DB
174 }
175
176 func setupHaEnv(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
177         psm, cm, _, db := setupHaEnvWithSentinels(commandsExists)
178         return psm, cm, db
179 }
180
181 func setupHaEnvWithSentinels(commandsExists bool) (*pubSubMock, *clientMock, []*MockRedisSentinel, *sdlgoredis.DB) {
182         setupVals := setupEnv(
183                 commandsExists,
184                 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
185                 "6376",
186                 "dbaasmaster",
187                 "26376",
188                 "",
189                 "3",
190         )
191         return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.rSentinel, setupVals.db[0]
192 }
193
194 func setupSingleEnv(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
195         setupVals := setupEnv(
196                 commandsExists,
197                 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
198                 "6376", "", "", "", "",
199         )
200         return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
201 }
202
203 func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nodeCnt string) setupEv {
204         var ret setupEv
205
206         dummyCommandInfo := redis.CommandInfo{
207                 Name: "dummy",
208         }
209
210         cmdResult := make(map[string]*redis.CommandInfo, 0)
211         if commandsExists {
212                 cmdResult = map[string]*redis.CommandInfo{
213                         "setie":    &dummyCommandInfo,
214                         "delie":    &dummyCommandInfo,
215                         "setiepub": &dummyCommandInfo,
216                         "setnxpub": &dummyCommandInfo,
217                         "msetmpub": &dummyCommandInfo,
218                         "delmpub":  &dummyCommandInfo,
219                 }
220         } else {
221                 cmdResult = map[string]*redis.CommandInfo{
222                         "dummy": &dummyCommandInfo,
223                 }
224         }
225
226         osmock := new(MockOS)
227         osmock.On("Getenv", "DBAAS_SERVICE_HOST", "localhost").Return(host)
228         osmock.On("Getenv", "DBAAS_SERVICE_PORT", "6379").Return(port)
229         osmock.On("Getenv", "DBAAS_MASTER_NAME", "").Return(msname)
230         osmock.On("Getenv", "DBAAS_SERVICE_SENTINEL_PORT", "").Return(sntport)
231         osmock.On("Getenv", "DBAAS_CLUSTER_ADDR_LIST", "").Return(clsaddrlist)
232         osmock.On("Getenv", "DBAAS_SERVICE_NODE_COUNT", "").Return(nodeCnt)
233
234         pubSubMock, subscribeNotifications := setSubscribeNotifications()
235         smock := new(MockRedisSentinel)
236         ret.rSentinel = append(ret.rSentinel, smock)
237         clients := sdlgoredis.ReadConfigAndCreateDbClients(
238                 osmock,
239                 func(addr, port, clusterName string, isHa bool) sdlgoredis.RedisClient {
240                         clm := new(clientMock)
241                         clm.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
242                         ret.rClient = append(ret.rClient, clm)
243                         ret.pubSubMock = append(ret.pubSubMock, pubSubMock)
244                         return clm
245                 },
246                 subscribeNotifications,
247                 func(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
248                         s := &sdlgoredis.Sentinel{
249                                 IredisSentinelClient: smock,
250                                 Cfg:                  cfg,
251                         }
252                         return s
253                 },
254         )
255         ret.db = clients
256         return ret
257 }
258
259 func TestCloseDbSuccessfully(t *testing.T) {
260         _, r, db := setupHaEnv(true)
261         r.On("Close").Return(nil)
262         err := db.CloseDB()
263         assert.Nil(t, err)
264         r.AssertExpectations(t)
265 }
266
267 func TestCloseDbFailure(t *testing.T) {
268         _, r, db := setupHaEnv(true)
269         r.On("Close").Return(errors.New("Some error"))
270         err := db.CloseDB()
271         assert.NotNil(t, err)
272         r.AssertExpectations(t)
273 }
274
275 func TestMSetSuccessfully(t *testing.T) {
276         _, r, db := setupHaEnv(true)
277         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
278         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
279         err := db.MSet("key1", "value1", "key2", 2)
280         assert.Nil(t, err)
281         r.AssertExpectations(t)
282 }
283
284 func TestMSetFailure(t *testing.T) {
285         _, r, db := setupHaEnv(true)
286         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
287         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
288         err := db.MSet("key1", "value1", "key2", 2)
289         assert.NotNil(t, err)
290         r.AssertExpectations(t)
291 }
292
293 func TestMSetMPubSuccessfully(t *testing.T) {
294         _, r, db := setupHaEnv(true)
295         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
296                 "chan1", "event1", "chan2", "event2"}
297         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
298         assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
299                 "key1", "val1", "key2", "val2"))
300         r.AssertExpectations(t)
301 }
302
303 func TestMsetMPubFailure(t *testing.T) {
304         _, r, db := setupHaEnv(true)
305         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
306                 "chan1", "event1", "chan2", "event2"}
307         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
308         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
309                 "key1", "val1", "key2", "val2"))
310         r.AssertExpectations(t)
311 }
312
313 func TestMSetMPubCommandMissing(t *testing.T) {
314         _, r, db := setupHaEnv(false)
315         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
316                 "chan1", "event1", "chan2", "event2"}
317         r.AssertNotCalled(t, "Do", expectedMessage)
318         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
319                 "key1", "val1", "key2", "val2"))
320         r.AssertExpectations(t)
321
322 }
323
324 func TestMGetSuccessfully(t *testing.T) {
325         _, r, db := setupHaEnv(true)
326         expectedKeys := []string{"key1", "key2", "key3"}
327         expectedResult := []interface{}{"val1", 2, nil}
328         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
329         result, err := db.MGet([]string{"key1", "key2", "key3"})
330         assert.Equal(t, result, expectedResult)
331         assert.Nil(t, err)
332         r.AssertExpectations(t)
333 }
334
335 func TestMGetFailure(t *testing.T) {
336         _, r, db := setupHaEnv(true)
337         expectedKeys := []string{"key1", "key2", "key3"}
338         expectedResult := []interface{}{nil}
339         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
340                 errors.New("Some error")))
341         result, err := db.MGet([]string{"key1", "key2", "key3"})
342         assert.Equal(t, result, expectedResult)
343         assert.NotNil(t, err)
344         r.AssertExpectations(t)
345 }
346
347 func TestDelMPubSuccessfully(t *testing.T) {
348         _, r, db := setupHaEnv(true)
349         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
350                 "chan2", "event2"}
351         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
352         assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
353                 []string{"key1", "key2"}))
354         r.AssertExpectations(t)
355 }
356
357 func TestDelMPubFailure(t *testing.T) {
358         _, r, db := setupHaEnv(true)
359         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
360                 "chan2", "event2"}
361         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
362         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
363                 []string{"key1", "key2"}))
364         r.AssertExpectations(t)
365 }
366
367 func TestDelMPubCommandMissing(t *testing.T) {
368         _, r, db := setupHaEnv(false)
369         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
370                 "chan2", "event2"}
371         r.AssertNotCalled(t, "Do", expectedMessage)
372         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
373                 []string{"key1", "key2"}))
374         r.AssertExpectations(t)
375 }
376
377 func TestDelSuccessfully(t *testing.T) {
378         _, r, db := setupHaEnv(true)
379         expectedKeys := []string{"key1", "key2"}
380         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
381         assert.Nil(t, db.Del([]string{"key1", "key2"}))
382         r.AssertExpectations(t)
383 }
384
385 func TestDelFailure(t *testing.T) {
386         _, r, db := setupHaEnv(true)
387         expectedKeys := []string{"key1", "key2"}
388         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
389         assert.NotNil(t, db.Del([]string{"key1", "key2"}))
390         r.AssertExpectations(t)
391 }
392
393 func TestKeysSuccessfully(t *testing.T) {
394         _, r, db := setupHaEnv(true)
395         expectedPattern := "pattern*"
396         expectedResult := []string{"pattern1", "pattern2"}
397         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
398         result, err := db.Keys("pattern*")
399         assert.Equal(t, result, expectedResult)
400         assert.Nil(t, err)
401         r.AssertExpectations(t)
402 }
403
404 func TestKeysFailure(t *testing.T) {
405         _, r, db := setupHaEnv(true)
406         expectedPattern := "pattern*"
407         expectedResult := []string{}
408         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
409                 errors.New("Some error")))
410         _, err := db.Keys("pattern*")
411         assert.NotNil(t, err)
412         r.AssertExpectations(t)
413 }
414
415 func TestSetIEKeyExists(t *testing.T) {
416         _, r, db := setupHaEnv(true)
417         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
418         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
419         result, err := db.SetIE("key", "olddata", "newdata")
420         assert.True(t, result)
421         assert.Nil(t, err)
422         r.AssertExpectations(t)
423 }
424
425 func TestSetIEKeyDoesntExists(t *testing.T) {
426         _, r, db := setupHaEnv(true)
427         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
428         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
429         result, err := db.SetIE("key", "olddata", "newdata")
430         assert.False(t, result)
431         assert.Nil(t, err)
432         r.AssertExpectations(t)
433 }
434
435 func TestSetIEFailure(t *testing.T) {
436         _, r, db := setupHaEnv(true)
437         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
438         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
439         result, err := db.SetIE("key", "olddata", "newdata")
440         assert.False(t, result)
441         assert.NotNil(t, err)
442         r.AssertExpectations(t)
443 }
444
445 func TestSetIECommandMissing(t *testing.T) {
446         _, r, db := setupHaEnv(false)
447         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
448         r.AssertNotCalled(t, "Do", expectedMessage)
449         result, err := db.SetIE("key", "olddata", "newdata")
450         assert.False(t, result)
451         assert.NotNil(t, err)
452         r.AssertExpectations(t)
453 }
454
455 func TestSetIEPubKeyExists(t *testing.T) {
456         _, r, db := setupHaEnv(true)
457         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
458         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
459         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
460         assert.True(t, result)
461         assert.Nil(t, err)
462         r.AssertExpectations(t)
463 }
464
465 func TestSetIEPubKeyDoesntExists(t *testing.T) {
466         _, r, db := setupHaEnv(true)
467         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
468         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
469         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
470         assert.False(t, result)
471         assert.Nil(t, err)
472         r.AssertExpectations(t)
473 }
474
475 func TestSetIEPubFailure(t *testing.T) {
476         _, r, db := setupHaEnv(true)
477         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
478         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
479         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
480         assert.False(t, result)
481         assert.NotNil(t, err)
482         r.AssertExpectations(t)
483 }
484
485 func TestSetIEPubCommandMissing(t *testing.T) {
486         _, r, db := setupHaEnv(false)
487         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
488         r.AssertNotCalled(t, "Do", expectedMessage)
489         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
490         assert.False(t, result)
491         assert.NotNil(t, err)
492         r.AssertExpectations(t)
493 }
494
495 func TestSetNXPubKeyDoesntExist(t *testing.T) {
496         _, r, db := setupHaEnv(true)
497         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
498         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
499         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
500         assert.True(t, result)
501         assert.Nil(t, err)
502         r.AssertExpectations(t)
503 }
504
505 func TestSetNXPubKeyExists(t *testing.T) {
506         _, r, db := setupHaEnv(true)
507         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
508         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
509         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
510         assert.False(t, result)
511         assert.Nil(t, err)
512         r.AssertExpectations(t)
513 }
514
515 func TestSetNXPubFailure(t *testing.T) {
516         _, r, db := setupHaEnv(true)
517         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
518         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
519         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
520         assert.False(t, result)
521         assert.NotNil(t, err)
522         r.AssertExpectations(t)
523 }
524
525 func TestSetNXPubCommandMissing(t *testing.T) {
526         _, r, db := setupHaEnv(false)
527         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
528         r.AssertNotCalled(t, "Do", expectedMessage)
529         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
530         assert.False(t, result)
531         assert.NotNil(t, err)
532         r.AssertExpectations(t)
533 }
534
535 func TestSetNXSuccessfully(t *testing.T) {
536         _, r, db := setupHaEnv(true)
537         expectedKey := "key"
538         expectedData := "data"
539         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
540         result, err := db.SetNX("key", "data", 0)
541         assert.True(t, result)
542         assert.Nil(t, err)
543         r.AssertExpectations(t)
544 }
545
546 func TestSetNXUnsuccessfully(t *testing.T) {
547         _, r, db := setupHaEnv(true)
548         expectedKey := "key"
549         expectedData := "data"
550         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
551         result, err := db.SetNX("key", "data", 0)
552         assert.False(t, result)
553         assert.Nil(t, err)
554         r.AssertExpectations(t)
555 }
556
557 func TestSetNXFailure(t *testing.T) {
558         _, r, db := setupHaEnv(true)
559         expectedKey := "key"
560         expectedData := "data"
561         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
562                 Return(redis.NewBoolResult(false, errors.New("Some error")))
563         result, err := db.SetNX("key", "data", 0)
564         assert.False(t, result)
565         assert.NotNil(t, err)
566         r.AssertExpectations(t)
567 }
568
569 func TestDelIEPubKeyDoesntExist(t *testing.T) {
570         _, r, db := setupHaEnv(true)
571         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
572         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
573         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
574         assert.False(t, result)
575         assert.Nil(t, err)
576         r.AssertExpectations(t)
577 }
578
579 func TestDelIEPubKeyExists(t *testing.T) {
580         _, r, db := setupHaEnv(true)
581         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
582         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
583         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
584         assert.True(t, result)
585         assert.Nil(t, err)
586         r.AssertExpectations(t)
587 }
588
589 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
590         _, r, db := setupHaEnv(true)
591         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
592         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
593         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
594         assert.True(t, result)
595         assert.Nil(t, err)
596         r.AssertExpectations(t)
597 }
598
599 func TestDelIEPubFailure(t *testing.T) {
600         _, r, db := setupHaEnv(true)
601         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
602         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
603         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
604         assert.False(t, result)
605         assert.NotNil(t, err)
606         r.AssertExpectations(t)
607 }
608
609 func TestDelIEPubCommandMissing(t *testing.T) {
610         _, r, db := setupHaEnv(false)
611         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
612         r.AssertNotCalled(t, "Do", expectedMessage)
613         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
614         assert.False(t, result)
615         assert.NotNil(t, err)
616         r.AssertExpectations(t)
617 }
618
619 func TestDelIEKeyDoesntExist(t *testing.T) {
620         _, r, db := setupHaEnv(true)
621         expectedMessage := []interface{}{"DELIE", "key", "data"}
622         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
623         result, err := db.DelIE("key", "data")
624         assert.False(t, result)
625         assert.Nil(t, err)
626         r.AssertExpectations(t)
627 }
628
629 func TestDelIEKeyExists(t *testing.T) {
630         _, r, db := setupHaEnv(true)
631         expectedMessage := []interface{}{"DELIE", "key", "data"}
632         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
633         result, err := db.DelIE("key", "data")
634         assert.True(t, result)
635         assert.Nil(t, err)
636         r.AssertExpectations(t)
637 }
638
639 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
640         _, r, db := setupHaEnv(true)
641         expectedMessage := []interface{}{"DELIE", "key", "data"}
642         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
643         result, err := db.DelIE("key", "data")
644         assert.True(t, result)
645         assert.Nil(t, err)
646         r.AssertExpectations(t)
647 }
648
649 func TestDelIEFailure(t *testing.T) {
650         _, r, db := setupHaEnv(true)
651         expectedMessage := []interface{}{"DELIE", "key", "data"}
652         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
653         result, err := db.DelIE("key", "data")
654         assert.False(t, result)
655         assert.NotNil(t, err)
656         r.AssertExpectations(t)
657 }
658
659 func TestDelIECommandMissing(t *testing.T) {
660         _, r, db := setupHaEnv(false)
661         expectedMessage := []interface{}{"DELIE", "key", "data"}
662         r.AssertNotCalled(t, "Do", expectedMessage)
663         result, err := db.DelIE("key", "data")
664         assert.False(t, result)
665         assert.NotNil(t, err)
666         r.AssertExpectations(t)
667 }
668
669 func TestSAddSuccessfully(t *testing.T) {
670         _, r, db := setupHaEnv(true)
671         expectedKey := "key"
672         expectedData := []interface{}{"data", 2}
673         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
674         assert.Nil(t, db.SAdd("key", "data", 2))
675         r.AssertExpectations(t)
676 }
677
678 func TestSAddFailure(t *testing.T) {
679         _, r, db := setupHaEnv(true)
680         expectedKey := "key"
681         expectedData := []interface{}{"data", 2}
682         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
683         assert.NotNil(t, db.SAdd("key", "data", 2))
684         r.AssertExpectations(t)
685 }
686
687 func TestSRemSuccessfully(t *testing.T) {
688         _, r, db := setupHaEnv(true)
689         expectedKey := "key"
690         expectedData := []interface{}{"data", 2}
691         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
692         assert.Nil(t, db.SRem("key", "data", 2))
693         r.AssertExpectations(t)
694 }
695
696 func TestSRemFailure(t *testing.T) {
697         _, r, db := setupHaEnv(true)
698         expectedKey := "key"
699         expectedData := []interface{}{"data", 2}
700         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
701         assert.NotNil(t, db.SRem("key", "data", 2))
702         r.AssertExpectations(t)
703 }
704
705 func TestSMembersSuccessfully(t *testing.T) {
706         _, r, db := setupHaEnv(true)
707         expectedKey := "key"
708         expectedResult := []string{"member1", "member2"}
709         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
710         result, err := db.SMembers("key")
711         assert.Equal(t, result, expectedResult)
712         assert.Nil(t, err)
713         r.AssertExpectations(t)
714 }
715
716 func TestSMembersFailure(t *testing.T) {
717         _, r, db := setupHaEnv(true)
718         expectedKey := "key"
719         expectedResult := []string{"member1", "member2"}
720         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
721                 errors.New("Some error")))
722         result, err := db.SMembers("key")
723         assert.Equal(t, result, expectedResult)
724         assert.NotNil(t, err)
725         r.AssertExpectations(t)
726 }
727
728 func TestSIsMemberIsMember(t *testing.T) {
729         _, r, db := setupHaEnv(true)
730         expectedKey := "key"
731         expectedData := "data"
732         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
733         result, err := db.SIsMember("key", "data")
734         assert.True(t, result)
735         assert.Nil(t, err)
736         r.AssertExpectations(t)
737 }
738
739 func TestSIsMemberIsNotMember(t *testing.T) {
740         _, r, db := setupHaEnv(true)
741         expectedKey := "key"
742         expectedData := "data"
743         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
744         result, err := db.SIsMember("key", "data")
745         assert.False(t, result)
746         assert.Nil(t, err)
747         r.AssertExpectations(t)
748 }
749
750 func TestSIsMemberFailure(t *testing.T) {
751         _, r, db := setupHaEnv(true)
752         expectedKey := "key"
753         expectedData := "data"
754         r.On("SIsMember", expectedKey, expectedData).
755                 Return(redis.NewBoolResult(false, errors.New("Some error")))
756         result, err := db.SIsMember("key", "data")
757         assert.False(t, result)
758         assert.NotNil(t, err)
759         r.AssertExpectations(t)
760 }
761
762 func TestSCardSuccessfully(t *testing.T) {
763         _, r, db := setupHaEnv(true)
764         expectedKey := "key"
765         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
766         result, err := db.SCard("key")
767         assert.Equal(t, int64(1), result)
768         assert.Nil(t, err)
769         r.AssertExpectations(t)
770 }
771
772 func TestSCardFailure(t *testing.T) {
773         _, r, db := setupHaEnv(true)
774         expectedKey := "key"
775         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
776         result, err := db.SCard("key")
777         assert.Equal(t, int64(1), result)
778         assert.NotNil(t, err)
779         r.AssertExpectations(t)
780 }
781
782 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
783         ps, r, db := setupHaEnv(true)
784         ch := make(chan *redis.Message)
785         msg := redis.Message{
786                 Channel: "{prefix}channel",
787                 Pattern: "pattern",
788                 Payload: "event",
789         }
790         ps.On("Channel").Return(ch)
791         ps.On("Unsubscribe").Return(nil)
792         ps.On("Close").Return(nil)
793         count := 0
794         receivedChannel := ""
795         db.SubscribeChannelDB(func(channel string, payload ...string) {
796                 count++
797                 receivedChannel = channel
798         }, "{prefix}", "---", "{prefix}channel")
799         ch <- &msg
800         db.UnsubscribeChannelDB("{prefix}channel")
801         time.Sleep(1 * time.Second)
802         assert.Equal(t, 1, count)
803         assert.Equal(t, "channel", receivedChannel)
804         r.AssertExpectations(t)
805         ps.AssertExpectations(t)
806 }
807
808 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
809         ps, r, db := setupHaEnv(true)
810         ch := make(chan *redis.Message)
811         msg1 := redis.Message{
812                 Channel: "{prefix}channel1",
813                 Pattern: "pattern",
814                 Payload: "event",
815         }
816         msg2 := redis.Message{
817                 Channel: "{prefix}channel2",
818                 Pattern: "pattern",
819                 Payload: "event",
820         }
821         ps.On("Channel").Return(ch)
822         ps.On("Subscribe").Return(nil)
823         ps.On("Unsubscribe").Return(nil)
824         ps.On("Unsubscribe").Return(nil)
825         ps.On("Close").Return(nil)
826         count := 0
827         receivedChannel1 := ""
828         db.SubscribeChannelDB(func(channel string, payload ...string) {
829                 count++
830                 receivedChannel1 = channel
831         }, "{prefix}", "---", "{prefix}channel1")
832         ch <- &msg1
833         receivedChannel2 := ""
834         db.SubscribeChannelDB(func(channel string, payload ...string) {
835                 count++
836                 receivedChannel2 = channel
837         }, "{prefix}", "---", "{prefix}channel2")
838
839         time.Sleep(1 * time.Second)
840         db.UnsubscribeChannelDB("{prefix}channel1")
841         ch <- &msg2
842         db.UnsubscribeChannelDB("{prefix}channel2")
843         time.Sleep(1 * time.Second)
844         assert.Equal(t, 2, count)
845         assert.Equal(t, "channel1", receivedChannel1)
846         assert.Equal(t, "channel2", receivedChannel2)
847         r.AssertExpectations(t)
848         ps.AssertExpectations(t)
849 }
850
851 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
852         ps, r, db := setupHaEnv(true)
853         ch := make(chan *redis.Message)
854         msg := redis.Message{
855                 Channel: "{prefix}channel",
856                 Pattern: "pattern",
857                 Payload: "event",
858         }
859         ps.On("Channel").Return(ch)
860         ps.On("Unsubscribe").Return(nil)
861         ps.On("Close").Return(nil)
862         count := 0
863         receivedChannel := ""
864
865         db.SubscribeChannelDB(func(channel string, payload ...string) {
866                 count++
867                 receivedChannel = channel
868         }, "{prefix}", "---", "{prefix}channel")
869         ch <- &msg
870         db.UnsubscribeChannelDB("{prefix}channel")
871         time.Sleep(1 * time.Second)
872
873         db.SubscribeChannelDB(func(channel string, payload ...string) {
874                 count++
875                 receivedChannel = channel
876         }, "{prefix}", "---", "{prefix}channel")
877         ch <- &msg
878         db.UnsubscribeChannelDB("{prefix}channel")
879
880         time.Sleep(1 * time.Second)
881         assert.Equal(t, 2, count)
882         assert.Equal(t, "channel", receivedChannel)
883         r.AssertExpectations(t)
884         ps.AssertExpectations(t)
885 }
886
887 func TestPTTLSuccessfully(t *testing.T) {
888         _, r, db := setupHaEnv(true)
889         expectedKey := "key"
890         expectedResult := time.Duration(1)
891         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
892                 nil))
893         result, err := db.PTTL("key")
894         assert.Equal(t, result, expectedResult)
895         assert.Nil(t, err)
896         r.AssertExpectations(t)
897 }
898
899 func TestPTTLFailure(t *testing.T) {
900         _, r, db := setupHaEnv(true)
901         expectedKey := "key"
902         expectedResult := time.Duration(1)
903         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
904                 errors.New("Some error")))
905         result, err := db.PTTL("key")
906         assert.Equal(t, result, expectedResult)
907         assert.NotNil(t, err)
908         r.AssertExpectations(t)
909 }
910
911 func TestPExpireIESuccessfully(t *testing.T) {
912         _, r, db := setupHaEnv(true)
913         expectedKey := "key"
914         expectedData := "data"
915         expectedDuration := strconv.FormatInt(int64(10000), 10)
916
917         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
918                 Return(redis.NewCmdResult(int64(1), nil))
919
920         err := db.PExpireIE("key", "data", 10*time.Second)
921         assert.Nil(t, err)
922         r.AssertExpectations(t)
923 }
924
925 func TestPExpireIEFailure(t *testing.T) {
926         _, r, db := setupHaEnv(true)
927         expectedKey := "key"
928         expectedData := "data"
929         expectedDuration := strconv.FormatInt(int64(10000), 10)
930
931         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
932                 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
933
934         err := db.PExpireIE("key", "data", 10*time.Second)
935         assert.NotNil(t, err)
936         r.AssertExpectations(t)
937 }
938
939 func TestPExpireIELockNotHeld(t *testing.T) {
940         _, r, db := setupHaEnv(true)
941         expectedKey := "key"
942         expectedData := "data"
943         expectedDuration := strconv.FormatInt(int64(10000), 10)
944
945         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
946                 Return(redis.NewCmdResult(int64(0), nil))
947
948         err := db.PExpireIE("key", "data", 10*time.Second)
949         assert.NotNil(t, err)
950         r.AssertExpectations(t)
951 }
952
953 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
954         setupVals := setupEnv(
955                 true,
956                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
957         )
958         assert.Equal(t, 1, len(setupVals.rClient))
959         assert.Equal(t, 1, len(setupVals.db))
960
961         expectedKeysAndValues := []interface{}{"key1", "value1"}
962         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
963         err := setupVals.db[0].MSet("key1", "value1")
964         assert.Nil(t, err)
965         setupVals.rClient[0].AssertExpectations(t)
966 }
967
968 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
969         setupVals := setupEnv(
970                 true,
971                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
972         )
973         assert.Equal(t, 1, len(setupVals.rClient))
974         assert.Equal(t, 1, len(setupVals.db))
975
976         expectedKeysAndValues := []interface{}{"key1", "value1"}
977         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
978         err := setupVals.db[0].MSet("key1", "value1")
979         assert.Nil(t, err)
980         setupVals.rClient[0].AssertExpectations(t)
981 }
982
983 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
984         setupVals := setupEnv(
985                 true,
986                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
987                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
988         )
989         assert.Equal(t, 2, len(setupVals.rClient))
990         assert.Equal(t, 2, len(setupVals.db))
991
992         expectedKeysAndValues := []interface{}{"key1", "value1"}
993         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
994         err := setupVals.db[0].MSet("key1", "value1")
995         assert.Nil(t, err)
996         setupVals.rClient[0].AssertExpectations(t)
997
998         expectedKeysAndValues = []interface{}{"key2", "value2"}
999         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1000         err = setupVals.db[1].MSet("key2", "value2")
1001         assert.Nil(t, err)
1002         setupVals.rClient[0].AssertExpectations(t)
1003         setupVals.rClient[1].AssertExpectations(t)
1004 }
1005
1006 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1007         setupVals := setupEnv(
1008                 true,
1009                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
1010                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1011         )
1012         assert.Equal(t, 2, len(setupVals.rClient))
1013         assert.Equal(t, 2, len(setupVals.db))
1014
1015         expectedKeysAndValues := []interface{}{"key1", "value1"}
1016         setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1017         err := setupVals.db[0].MSet("key1", "value1")
1018         assert.Nil(t, err)
1019         setupVals.rClient[0].AssertExpectations(t)
1020
1021         expectedKeysAndValues = []interface{}{"key2", "value2"}
1022         setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1023         err = setupVals.db[1].MSet("key2", "value2")
1024         assert.Nil(t, err)
1025         setupVals.rClient[0].AssertExpectations(t)
1026         setupVals.rClient[1].AssertExpectations(t)
1027 }
1028
1029 func TestInfoOfMasterRedisWithTwoSlavesSuccessfully(t *testing.T) {
1030         _, r, db := setupHaEnv(true)
1031         redisInfo := "# Replication\r\n" +
1032                 "role:master\r\n" +
1033                 "connected_slaves:2\r\n" +
1034                 "min_slaves_good_slaves:2\r\n" +
1035                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1036                 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1037         expInfo := &sdlgoredis.DbInfo{
1038                 Fields: sdlgoredis.DbInfoFields{
1039                         MasterRole:          true,
1040                         ConnectedReplicaCnt: 2,
1041                 },
1042         }
1043
1044         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1045         info, err := db.Info()
1046         assert.Nil(t, err)
1047         assert.Equal(t, expInfo, info)
1048         r.AssertExpectations(t)
1049 }
1050
1051 func TestInfoOfMasterRedisWithOneSlaveOnlineAndOtherSlaveNotOnlineSuccessfully(t *testing.T) {
1052         _, r, db := setupHaEnv(true)
1053         redisInfo := "# Replication\r\n" +
1054                 "role:master\r\n" +
1055                 "connected_slaves:1\r\n" +
1056                 "min_slaves_good_slaves:2\r\n" +
1057                 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1058                 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1059         expInfo := &sdlgoredis.DbInfo{
1060                 Fields: sdlgoredis.DbInfoFields{
1061                         MasterRole:          true,
1062                         ConnectedReplicaCnt: 1,
1063                 },
1064         }
1065
1066         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1067         info, err := db.Info()
1068         assert.Nil(t, err)
1069         assert.Equal(t, expInfo, info)
1070         r.AssertExpectations(t)
1071 }
1072
1073 func TestInfoOfStandaloneMasterRedisSuccessfully(t *testing.T) {
1074         _, r, db := setupHaEnv(true)
1075         redisInfo := "# Replication\r\n" +
1076                 "role:master\r\n" +
1077                 "connected_slaves:0\r\n" +
1078                 "min_slaves_good_slaves:0\r\n"
1079         expInfo := &sdlgoredis.DbInfo{
1080                 Fields: sdlgoredis.DbInfoFields{
1081                         MasterRole:          true,
1082                         ConnectedReplicaCnt: 0,
1083                 },
1084         }
1085
1086         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1087         info, err := db.Info()
1088         assert.Nil(t, err)
1089         assert.Equal(t, expInfo, info)
1090         r.AssertExpectations(t)
1091 }
1092
1093 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1094         _, r, db := setupHaEnv(true)
1095         redisInfo := "!#¤%&?+?´-\r\n"
1096         expInfo := &sdlgoredis.DbInfo{}
1097
1098         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1099         info, err := db.Info()
1100         assert.Nil(t, err)
1101         assert.Equal(t, expInfo, info)
1102         r.AssertExpectations(t)
1103 }
1104
1105 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1106         _, r, db := setupHaEnv(true)
1107         var redisInfo string
1108         expInfo := &sdlgoredis.DbInfo{
1109                 Fields: sdlgoredis.DbInfoFields{
1110                         MasterRole: false,
1111                 },
1112         }
1113
1114         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1115         info, err := db.Info()
1116         assert.Nil(t, err)
1117         assert.Equal(t, expInfo, info)
1118         r.AssertExpectations(t)
1119 }
1120
1121 func TestStateWithMasterAndTwoSlaveRedisSuccessfully(t *testing.T) {
1122         _, r, s, db := setupHaEnvWithSentinels(true)
1123         redisMasterState := map[string]string{
1124                 "role-reported": "master",
1125         }
1126         redisSlavesState := make([]interface{}, 2)
1127         redisSlavesState[0] = []interface{}{
1128                 "role-reported", "slave",
1129                 "ip", "10.20.30.40",
1130                 "port", "6379",
1131                 "flags", "slave",
1132                 "master-link-status", "up",
1133         }
1134         redisSlavesState[1] = []interface{}{
1135                 "master-link-status", "up",
1136                 "ip", "10.20.30.50",
1137                 "flags", "slave",
1138                 "port", "30000",
1139                 "role-reported", "slave",
1140         }
1141
1142         expState := &sdlgoredis.DbState{
1143                 MasterDbState: sdlgoredis.MasterDbState{
1144                         Fields: sdlgoredis.MasterDbStateFields{
1145                                 Role: "master",
1146                         },
1147                 },
1148                 ReplicasDbState: &sdlgoredis.ReplicasDbState{
1149                         States: []*sdlgoredis.ReplicaDbState{
1150                                 &sdlgoredis.ReplicaDbState{
1151                                         Fields: sdlgoredis.ReplicaDbStateFields{
1152                                                 Role:             "slave",
1153                                                 Ip:               "10.20.30.40",
1154                                                 Port:             "6379",
1155                                                 MasterLinkStatus: "up",
1156                                                 Flags:            "slave",
1157                                         },
1158                                 },
1159                                 &sdlgoredis.ReplicaDbState{
1160                                         Fields: sdlgoredis.ReplicaDbStateFields{
1161                                                 Role:             "slave",
1162                                                 Ip:               "10.20.30.50",
1163                                                 Port:             "30000",
1164                                                 MasterLinkStatus: "up",
1165                                                 Flags:            "slave",
1166                                         },
1167                                 },
1168                         },
1169                 },
1170         }
1171
1172         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisMasterState, nil))
1173         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisSlavesState, nil))
1174         ret, err := db.State()
1175         assert.Nil(t, err)
1176         assert.Equal(t, expState, ret)
1177         r.AssertExpectations(t)
1178 }
1179
1180 func TestStateWithMasterAndOneSlaveRedisFailureInMasterRedisCall(t *testing.T) {
1181         _, r, s, db := setupHaEnvWithSentinels(true)
1182         redisMasterState := map[string]string{}
1183         redisSlavesState := make([]interface{}, 1)
1184         redisSlavesState[0] = []interface{}{
1185                 "role-reported", "slave",
1186                 "ip", "10.20.30.40",
1187                 "port", "6379",
1188                 "flags", "slave",
1189                 "master-link-status", "up",
1190         }
1191
1192         expState := &sdlgoredis.DbState{
1193                 MasterDbState: sdlgoredis.MasterDbState{
1194                         Err: errors.New("Some error"),
1195                 },
1196                 ReplicasDbState: &sdlgoredis.ReplicasDbState{
1197                         States: []*sdlgoredis.ReplicaDbState{
1198                                 &sdlgoredis.ReplicaDbState{
1199                                         Fields: sdlgoredis.ReplicaDbStateFields{
1200                                                 Role:             "slave",
1201                                                 Ip:               "10.20.30.40",
1202                                                 Port:             "6379",
1203                                                 MasterLinkStatus: "up",
1204                                                 Flags:            "slave",
1205                                         },
1206                                 },
1207                         },
1208                 },
1209         }
1210
1211         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisMasterState, errors.New("Some error")))
1212         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisSlavesState, nil))
1213         ret, err := db.State()
1214         assert.NotNil(t, err)
1215         assert.Equal(t, expState, ret)
1216         r.AssertExpectations(t)
1217 }
1218
1219 func TestStateWithMasterAndOneSlaveRedisFailureInSlavesRedisCall(t *testing.T) {
1220         _, r, s, db := setupHaEnvWithSentinels(true)
1221         redisMasterState := map[string]string{
1222                 "role-reported": "master",
1223         }
1224         redisSlavesState := make([]interface{}, 1)
1225         redisSlavesState[0] = []interface{}{}
1226
1227         expState := &sdlgoredis.DbState{
1228                 MasterDbState: sdlgoredis.MasterDbState{
1229                         Fields: sdlgoredis.MasterDbStateFields{
1230                                 Role: "master",
1231                         },
1232                 },
1233                 ReplicasDbState: &sdlgoredis.ReplicasDbState{
1234                         Err:    errors.New("Some error"),
1235                         States: []*sdlgoredis.ReplicaDbState{},
1236                 },
1237         }
1238
1239         s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisMasterState, nil))
1240         s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisSlavesState, errors.New("Some error")))
1241         ret, err := db.State()
1242         assert.NotNil(t, err)
1243         assert.Equal(t, expState, ret)
1244         r.AssertExpectations(t)
1245 }
1246
1247 func TestStateWithSingleMasterRedisSuccessfully(t *testing.T) {
1248         _, r, db := setupSingleEnv(true)
1249         redisInfo := "# Replication\r\n" +
1250                 "role:master\r\n" +
1251                 "connected_slaves:0\r\n" +
1252                 "min_slaves_good_slaves:0\r\n"
1253
1254         expState := &sdlgoredis.DbState{
1255                 MasterDbState: sdlgoredis.MasterDbState{
1256                         Fields: sdlgoredis.MasterDbStateFields{
1257                                 Role:  "master",
1258                                 Flags: "master",
1259                         },
1260                 },
1261         }
1262
1263         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1264         ret, err := db.State()
1265         assert.Nil(t, err)
1266         assert.Equal(t, expState, ret)
1267         r.AssertExpectations(t)
1268 }
1269
1270 func TestStateWithSingleMasterRedisFailureInInfoCall(t *testing.T) {
1271         _, r, db := setupSingleEnv(true)
1272         redisInfo := ""
1273         expState := &sdlgoredis.DbState{}
1274
1275         r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1276         ret, err := db.State()
1277         assert.NotNil(t, err)
1278         assert.Equal(t, expState, ret)
1279         r.AssertExpectations(t)
1280 }