Implement sentinel based DB capacity scaling
[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         "strconv"
28         "testing"
29         "time"
30
31         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
32         "github.com/go-redis/redis"
33         "github.com/stretchr/testify/assert"
34         "github.com/stretchr/testify/mock"
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() <-chan *redis.Message {
50         return m.Called().Get(0).(chan *redis.Message)
51 }
52
53 func (m *pubSubMock) Subscribe(channels ...string) error {
54         return m.Called().Error(0)
55 }
56
57 func (m *pubSubMock) Unsubscribe(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() *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(channels ...string) *redis.PubSub {
74         return m.Called(channels).Get(0).(*redis.PubSub)
75 }
76
77 func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
78         return m.Called(pairs).Get(0).(*redis.StatusCmd)
79 }
80
81 func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
82         return m.Called(args).Get(0).(*redis.Cmd)
83 }
84
85 func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
86         return m.Called(keys).Get(0).(*redis.SliceCmd)
87 }
88
89 func (m *clientMock) Del(keys ...string) *redis.IntCmd {
90         return m.Called(keys).Get(0).(*redis.IntCmd)
91 }
92
93 func (m *clientMock) Keys(pattern string) *redis.StringSliceCmd {
94         return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
95 }
96
97 func (m *clientMock) SetNX(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(key string, members ...interface{}) *redis.IntCmd {
102         return m.Called(key, members).Get(0).(*redis.IntCmd)
103 }
104
105 func (m *clientMock) SRem(key string, members ...interface{}) *redis.IntCmd {
106         return m.Called(key, members).Get(0).(*redis.IntCmd)
107 }
108
109 func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
110         return m.Called(key).Get(0).(*redis.StringSliceCmd)
111 }
112
113 func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
114         return m.Called(key, member).Get(0).(*redis.BoolCmd)
115 }
116
117 func (m *clientMock) SCard(key string) *redis.IntCmd {
118         return m.Called(key).Get(0).(*redis.IntCmd)
119 }
120
121 func (m *clientMock) PTTL(key string) *redis.DurationCmd {
122         return m.Called(key).Get(0).(*redis.DurationCmd)
123 }
124
125 func (m *clientMock) Eval(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(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(scripts ...string) *redis.BoolSliceCmd {
134         return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
135 }
136
137 func (m *clientMock) ScriptLoad(script string) *redis.StringCmd {
138         return m.Called(script).Get(0).(*redis.StringCmd)
139 }
140
141 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
142         mock := new(pubSubMock)
143         return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
144                 return mock
145         }
146 }
147
148 func (m *MockOS) Getenv(key string, defValue string) string {
149         a := m.Called(key, defValue)
150         return a.String(0)
151 }
152
153 func setup(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
154         mock := new(clientMock)
155         pubSubMock, subscribeNotifications := setSubscribeNotifications()
156         db := sdlgoredis.CreateDB(mock, subscribeNotifications)
157
158         dummyCommandInfo := redis.CommandInfo{
159                 Name: "dummy",
160         }
161         cmdResult := make(map[string]*redis.CommandInfo, 0)
162
163         if commandsExists {
164                 cmdResult = map[string]*redis.CommandInfo{
165                         "setie":    &dummyCommandInfo,
166                         "delie":    &dummyCommandInfo,
167                         "setiepub": &dummyCommandInfo,
168                         "setnxpub": &dummyCommandInfo,
169                         "msetmpub": &dummyCommandInfo,
170                         "delmpub":  &dummyCommandInfo,
171                 }
172         } else {
173                 cmdResult = map[string]*redis.CommandInfo{
174                         "dummy": &dummyCommandInfo,
175                 }
176         }
177
178         mock.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
179         db.CheckCommands()
180         return pubSubMock, mock, db
181 }
182
183 func setupEnv(host, port, msname, sntport, clsaddrlist string) ([]*clientMock, []*sdlgoredis.DB) {
184         var clmocks []*clientMock
185
186         dummyCommandInfo := redis.CommandInfo{
187                 Name: "dummy",
188         }
189         cmdResult := make(map[string]*redis.CommandInfo, 0)
190
191         cmdResult = map[string]*redis.CommandInfo{
192                 "dummy": &dummyCommandInfo,
193         }
194
195         osmock := new(MockOS)
196         osmock.On("Getenv", "DBAAS_SERVICE_HOST", "localhost").Return(host)
197         osmock.On("Getenv", "DBAAS_SERVICE_PORT", "6379").Return(port)
198         osmock.On("Getenv", "DBAAS_MASTER_NAME", "").Return(msname)
199         osmock.On("Getenv", "DBAAS_SERVICE_SENTINEL_PORT", "").Return(sntport)
200         osmock.On("Getenv", "DBAAS_CLUSTER_ADDR_LIST", "").Return(clsaddrlist)
201
202         clients := sdlgoredis.ReadConfigAndCreateDbClients(
203                 osmock,
204                 func(addr, port, clusterName string, isHa bool) sdlgoredis.RedisClient {
205                         clm := new(clientMock)
206                         clm.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
207                         clmocks = append(clmocks, clm)
208                         return clm
209                 },
210         )
211
212         return clmocks, clients
213 }
214
215 func TestCloseDbSuccessfully(t *testing.T) {
216         _, r, db := setup(true)
217         r.On("Close").Return(nil)
218         err := db.CloseDB()
219         assert.Nil(t, err)
220         r.AssertExpectations(t)
221 }
222
223 func TestCloseDbFailure(t *testing.T) {
224         _, r, db := setup(true)
225         r.On("Close").Return(errors.New("Some error"))
226         err := db.CloseDB()
227         assert.NotNil(t, err)
228         r.AssertExpectations(t)
229 }
230
231 func TestMSetSuccessfully(t *testing.T) {
232         _, r, db := setup(true)
233         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
234         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
235         err := db.MSet("key1", "value1", "key2", 2)
236         assert.Nil(t, err)
237         r.AssertExpectations(t)
238 }
239
240 func TestMSetFailure(t *testing.T) {
241         _, r, db := setup(true)
242         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
243         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
244         err := db.MSet("key1", "value1", "key2", 2)
245         assert.NotNil(t, err)
246         r.AssertExpectations(t)
247 }
248
249 func TestMSetMPubSuccessfully(t *testing.T) {
250         _, r, db := setup(true)
251         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
252                 "chan1", "event1", "chan2", "event2"}
253         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
254         assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
255                 "key1", "val1", "key2", "val2"))
256         r.AssertExpectations(t)
257 }
258
259 func TestMsetMPubFailure(t *testing.T) {
260         _, r, db := setup(true)
261         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
262                 "chan1", "event1", "chan2", "event2"}
263         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
264         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
265                 "key1", "val1", "key2", "val2"))
266         r.AssertExpectations(t)
267 }
268
269 func TestMSetMPubCommandMissing(t *testing.T) {
270         _, r, db := setup(false)
271         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
272                 "chan1", "event1", "chan2", "event2"}
273         r.AssertNotCalled(t, "Do", expectedMessage)
274         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
275                 "key1", "val1", "key2", "val2"))
276         r.AssertExpectations(t)
277
278 }
279
280 func TestMGetSuccessfully(t *testing.T) {
281         _, r, db := setup(true)
282         expectedKeys := []string{"key1", "key2", "key3"}
283         expectedResult := []interface{}{"val1", 2, nil}
284         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
285         result, err := db.MGet([]string{"key1", "key2", "key3"})
286         assert.Equal(t, result, expectedResult)
287         assert.Nil(t, err)
288         r.AssertExpectations(t)
289 }
290
291 func TestMGetFailure(t *testing.T) {
292         _, r, db := setup(true)
293         expectedKeys := []string{"key1", "key2", "key3"}
294         expectedResult := []interface{}{nil}
295         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
296                 errors.New("Some error")))
297         result, err := db.MGet([]string{"key1", "key2", "key3"})
298         assert.Equal(t, result, expectedResult)
299         assert.NotNil(t, err)
300         r.AssertExpectations(t)
301 }
302
303 func TestDelMPubSuccessfully(t *testing.T) {
304         _, r, db := setup(true)
305         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
306                 "chan2", "event2"}
307         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
308         assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
309                 []string{"key1", "key2"}))
310         r.AssertExpectations(t)
311 }
312
313 func TestDelMPubFailure(t *testing.T) {
314         _, r, db := setup(true)
315         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
316                 "chan2", "event2"}
317         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
318         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
319                 []string{"key1", "key2"}))
320         r.AssertExpectations(t)
321 }
322
323 func TestDelMPubCommandMissing(t *testing.T) {
324         _, r, db := setup(false)
325         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
326                 "chan2", "event2"}
327         r.AssertNotCalled(t, "Do", expectedMessage)
328         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
329                 []string{"key1", "key2"}))
330         r.AssertExpectations(t)
331 }
332
333 func TestDelSuccessfully(t *testing.T) {
334         _, r, db := setup(true)
335         expectedKeys := []string{"key1", "key2"}
336         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
337         assert.Nil(t, db.Del([]string{"key1", "key2"}))
338         r.AssertExpectations(t)
339 }
340
341 func TestDelFailure(t *testing.T) {
342         _, r, db := setup(true)
343         expectedKeys := []string{"key1", "key2"}
344         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
345         assert.NotNil(t, db.Del([]string{"key1", "key2"}))
346         r.AssertExpectations(t)
347 }
348
349 func TestKeysSuccessfully(t *testing.T) {
350         _, r, db := setup(true)
351         expectedPattern := "pattern*"
352         expectedResult := []string{"pattern1", "pattern2"}
353         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
354         result, err := db.Keys("pattern*")
355         assert.Equal(t, result, expectedResult)
356         assert.Nil(t, err)
357         r.AssertExpectations(t)
358 }
359
360 func TestKeysFailure(t *testing.T) {
361         _, r, db := setup(true)
362         expectedPattern := "pattern*"
363         expectedResult := []string{}
364         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
365                 errors.New("Some error")))
366         _, err := db.Keys("pattern*")
367         assert.NotNil(t, err)
368         r.AssertExpectations(t)
369 }
370
371 func TestSetIEKeyExists(t *testing.T) {
372         _, r, db := setup(true)
373         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
374         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
375         result, err := db.SetIE("key", "olddata", "newdata")
376         assert.True(t, result)
377         assert.Nil(t, err)
378         r.AssertExpectations(t)
379 }
380
381 func TestSetIEKeyDoesntExists(t *testing.T) {
382         _, r, db := setup(true)
383         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
384         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
385         result, err := db.SetIE("key", "olddata", "newdata")
386         assert.False(t, result)
387         assert.Nil(t, err)
388         r.AssertExpectations(t)
389 }
390
391 func TestSetIEFailure(t *testing.T) {
392         _, r, db := setup(true)
393         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
394         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
395         result, err := db.SetIE("key", "olddata", "newdata")
396         assert.False(t, result)
397         assert.NotNil(t, err)
398         r.AssertExpectations(t)
399 }
400
401 func TestSetIECommandMissing(t *testing.T) {
402         _, r, db := setup(false)
403         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
404         r.AssertNotCalled(t, "Do", expectedMessage)
405         result, err := db.SetIE("key", "olddata", "newdata")
406         assert.False(t, result)
407         assert.NotNil(t, err)
408         r.AssertExpectations(t)
409 }
410
411 func TestSetIEPubKeyExists(t *testing.T) {
412         _, r, db := setup(true)
413         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
414         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
415         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
416         assert.True(t, result)
417         assert.Nil(t, err)
418         r.AssertExpectations(t)
419 }
420
421 func TestSetIEPubKeyDoesntExists(t *testing.T) {
422         _, r, db := setup(true)
423         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
424         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
425         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
426         assert.False(t, result)
427         assert.Nil(t, err)
428         r.AssertExpectations(t)
429 }
430
431 func TestSetIEPubFailure(t *testing.T) {
432         _, r, db := setup(true)
433         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
434         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
435         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
436         assert.False(t, result)
437         assert.NotNil(t, err)
438         r.AssertExpectations(t)
439 }
440
441 func TestSetIEPubCommandMissing(t *testing.T) {
442         _, r, db := setup(false)
443         expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
444         r.AssertNotCalled(t, "Do", expectedMessage)
445         result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
446         assert.False(t, result)
447         assert.NotNil(t, err)
448         r.AssertExpectations(t)
449 }
450
451 func TestSetNXPubKeyDoesntExist(t *testing.T) {
452         _, r, db := setup(true)
453         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
454         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
455         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
456         assert.True(t, result)
457         assert.Nil(t, err)
458         r.AssertExpectations(t)
459 }
460
461 func TestSetNXPubKeyExists(t *testing.T) {
462         _, r, db := setup(true)
463         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
464         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
465         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
466         assert.False(t, result)
467         assert.Nil(t, err)
468         r.AssertExpectations(t)
469 }
470
471 func TestSetNXPubFailure(t *testing.T) {
472         _, r, db := setup(true)
473         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
474         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
475         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
476         assert.False(t, result)
477         assert.NotNil(t, err)
478         r.AssertExpectations(t)
479 }
480
481 func TestSetNXPubCommandMissing(t *testing.T) {
482         _, r, db := setup(false)
483         expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
484         r.AssertNotCalled(t, "Do", expectedMessage)
485         result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
486         assert.False(t, result)
487         assert.NotNil(t, err)
488         r.AssertExpectations(t)
489 }
490
491 func TestSetNXSuccessfully(t *testing.T) {
492         _, r, db := setup(true)
493         expectedKey := "key"
494         expectedData := "data"
495         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
496         result, err := db.SetNX("key", "data", 0)
497         assert.True(t, result)
498         assert.Nil(t, err)
499         r.AssertExpectations(t)
500 }
501
502 func TestSetNXUnsuccessfully(t *testing.T) {
503         _, r, db := setup(true)
504         expectedKey := "key"
505         expectedData := "data"
506         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
507         result, err := db.SetNX("key", "data", 0)
508         assert.False(t, result)
509         assert.Nil(t, err)
510         r.AssertExpectations(t)
511 }
512
513 func TestSetNXFailure(t *testing.T) {
514         _, r, db := setup(true)
515         expectedKey := "key"
516         expectedData := "data"
517         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
518                 Return(redis.NewBoolResult(false, errors.New("Some error")))
519         result, err := db.SetNX("key", "data", 0)
520         assert.False(t, result)
521         assert.NotNil(t, err)
522         r.AssertExpectations(t)
523 }
524
525 func TestDelIEPubKeyDoesntExist(t *testing.T) {
526         _, r, db := setup(true)
527         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
528         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
529         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
530         assert.False(t, result)
531         assert.Nil(t, err)
532         r.AssertExpectations(t)
533 }
534
535 func TestDelIEPubKeyExists(t *testing.T) {
536         _, r, db := setup(true)
537         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
538         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
539         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
540         assert.True(t, result)
541         assert.Nil(t, err)
542         r.AssertExpectations(t)
543 }
544
545 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
546         _, r, db := setup(true)
547         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
548         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
549         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
550         assert.True(t, result)
551         assert.Nil(t, err)
552         r.AssertExpectations(t)
553 }
554
555 func TestDelIEPubFailure(t *testing.T) {
556         _, r, db := setup(true)
557         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
558         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
559         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
560         assert.False(t, result)
561         assert.NotNil(t, err)
562         r.AssertExpectations(t)
563 }
564
565 func TestDelIEPubCommandMissing(t *testing.T) {
566         _, r, db := setup(false)
567         expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
568         r.AssertNotCalled(t, "Do", expectedMessage)
569         result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
570         assert.False(t, result)
571         assert.NotNil(t, err)
572         r.AssertExpectations(t)
573 }
574
575 func TestDelIEKeyDoesntExist(t *testing.T) {
576         _, r, db := setup(true)
577         expectedMessage := []interface{}{"DELIE", "key", "data"}
578         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
579         result, err := db.DelIE("key", "data")
580         assert.False(t, result)
581         assert.Nil(t, err)
582         r.AssertExpectations(t)
583 }
584
585 func TestDelIEKeyExists(t *testing.T) {
586         _, r, db := setup(true)
587         expectedMessage := []interface{}{"DELIE", "key", "data"}
588         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
589         result, err := db.DelIE("key", "data")
590         assert.True(t, result)
591         assert.Nil(t, err)
592         r.AssertExpectations(t)
593 }
594
595 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
596         _, r, db := setup(true)
597         expectedMessage := []interface{}{"DELIE", "key", "data"}
598         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
599         result, err := db.DelIE("key", "data")
600         assert.True(t, result)
601         assert.Nil(t, err)
602         r.AssertExpectations(t)
603 }
604
605 func TestDelIEFailure(t *testing.T) {
606         _, r, db := setup(true)
607         expectedMessage := []interface{}{"DELIE", "key", "data"}
608         r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
609         result, err := db.DelIE("key", "data")
610         assert.False(t, result)
611         assert.NotNil(t, err)
612         r.AssertExpectations(t)
613 }
614
615 func TestDelIECommandMissing(t *testing.T) {
616         _, r, db := setup(false)
617         expectedMessage := []interface{}{"DELIE", "key", "data"}
618         r.AssertNotCalled(t, "Do", expectedMessage)
619         result, err := db.DelIE("key", "data")
620         assert.False(t, result)
621         assert.NotNil(t, err)
622         r.AssertExpectations(t)
623 }
624
625 func TestSAddSuccessfully(t *testing.T) {
626         _, r, db := setup(true)
627         expectedKey := "key"
628         expectedData := []interface{}{"data", 2}
629         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
630         assert.Nil(t, db.SAdd("key", "data", 2))
631         r.AssertExpectations(t)
632 }
633
634 func TestSAddFailure(t *testing.T) {
635         _, r, db := setup(true)
636         expectedKey := "key"
637         expectedData := []interface{}{"data", 2}
638         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
639         assert.NotNil(t, db.SAdd("key", "data", 2))
640         r.AssertExpectations(t)
641 }
642
643 func TestSRemSuccessfully(t *testing.T) {
644         _, r, db := setup(true)
645         expectedKey := "key"
646         expectedData := []interface{}{"data", 2}
647         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
648         assert.Nil(t, db.SRem("key", "data", 2))
649         r.AssertExpectations(t)
650 }
651
652 func TestSRemFailure(t *testing.T) {
653         _, r, db := setup(true)
654         expectedKey := "key"
655         expectedData := []interface{}{"data", 2}
656         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
657         assert.NotNil(t, db.SRem("key", "data", 2))
658         r.AssertExpectations(t)
659 }
660
661 func TestSMembersSuccessfully(t *testing.T) {
662         _, r, db := setup(true)
663         expectedKey := "key"
664         expectedResult := []string{"member1", "member2"}
665         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
666         result, err := db.SMembers("key")
667         assert.Equal(t, result, expectedResult)
668         assert.Nil(t, err)
669         r.AssertExpectations(t)
670 }
671
672 func TestSMembersFailure(t *testing.T) {
673         _, r, db := setup(true)
674         expectedKey := "key"
675         expectedResult := []string{"member1", "member2"}
676         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
677                 errors.New("Some error")))
678         result, err := db.SMembers("key")
679         assert.Equal(t, result, expectedResult)
680         assert.NotNil(t, err)
681         r.AssertExpectations(t)
682 }
683
684 func TestSIsMemberIsMember(t *testing.T) {
685         _, r, db := setup(true)
686         expectedKey := "key"
687         expectedData := "data"
688         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
689         result, err := db.SIsMember("key", "data")
690         assert.True(t, result)
691         assert.Nil(t, err)
692         r.AssertExpectations(t)
693 }
694
695 func TestSIsMemberIsNotMember(t *testing.T) {
696         _, r, db := setup(true)
697         expectedKey := "key"
698         expectedData := "data"
699         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
700         result, err := db.SIsMember("key", "data")
701         assert.False(t, result)
702         assert.Nil(t, err)
703         r.AssertExpectations(t)
704 }
705
706 func TestSIsMemberFailure(t *testing.T) {
707         _, r, db := setup(true)
708         expectedKey := "key"
709         expectedData := "data"
710         r.On("SIsMember", expectedKey, expectedData).
711                 Return(redis.NewBoolResult(false, errors.New("Some error")))
712         result, err := db.SIsMember("key", "data")
713         assert.False(t, result)
714         assert.NotNil(t, err)
715         r.AssertExpectations(t)
716 }
717
718 func TestSCardSuccessfully(t *testing.T) {
719         _, r, db := setup(true)
720         expectedKey := "key"
721         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
722         result, err := db.SCard("key")
723         assert.Equal(t, int64(1), result)
724         assert.Nil(t, err)
725         r.AssertExpectations(t)
726 }
727
728 func TestSCardFailure(t *testing.T) {
729         _, r, db := setup(true)
730         expectedKey := "key"
731         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
732         result, err := db.SCard("key")
733         assert.Equal(t, int64(1), result)
734         assert.NotNil(t, err)
735         r.AssertExpectations(t)
736 }
737
738 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
739         ps, r, db := setup(true)
740         ch := make(chan *redis.Message)
741         msg := redis.Message{
742                 Channel: "{prefix}channel",
743                 Pattern: "pattern",
744                 Payload: "event",
745         }
746         ps.On("Channel").Return(ch)
747         ps.On("Unsubscribe").Return(nil)
748         ps.On("Close").Return(nil)
749         count := 0
750         receivedChannel := ""
751         db.SubscribeChannelDB(func(channel string, payload ...string) {
752                 count++
753                 receivedChannel = channel
754         }, "{prefix}", "---", "{prefix}channel")
755         ch <- &msg
756         db.UnsubscribeChannelDB("{prefix}channel")
757         time.Sleep(1 * time.Second)
758         assert.Equal(t, 1, count)
759         assert.Equal(t, "channel", receivedChannel)
760         r.AssertExpectations(t)
761         ps.AssertExpectations(t)
762 }
763
764 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
765         ps, r, db := setup(true)
766         ch := make(chan *redis.Message)
767         msg1 := redis.Message{
768                 Channel: "{prefix}channel1",
769                 Pattern: "pattern",
770                 Payload: "event",
771         }
772         msg2 := redis.Message{
773                 Channel: "{prefix}channel2",
774                 Pattern: "pattern",
775                 Payload: "event",
776         }
777         ps.On("Channel").Return(ch)
778         ps.On("Subscribe").Return(nil)
779         ps.On("Unsubscribe").Return(nil)
780         ps.On("Unsubscribe").Return(nil)
781         ps.On("Close").Return(nil)
782         count := 0
783         receivedChannel1 := ""
784         db.SubscribeChannelDB(func(channel string, payload ...string) {
785                 count++
786                 receivedChannel1 = channel
787         }, "{prefix}", "---", "{prefix}channel1")
788         ch <- &msg1
789         receivedChannel2 := ""
790         db.SubscribeChannelDB(func(channel string, payload ...string) {
791                 count++
792                 receivedChannel2 = channel
793         }, "{prefix}", "---", "{prefix}channel2")
794
795         time.Sleep(1 * time.Second)
796         db.UnsubscribeChannelDB("{prefix}channel1")
797         ch <- &msg2
798         db.UnsubscribeChannelDB("{prefix}channel2")
799         time.Sleep(1 * time.Second)
800         assert.Equal(t, 2, count)
801         assert.Equal(t, "channel1", receivedChannel1)
802         assert.Equal(t, "channel2", receivedChannel2)
803         r.AssertExpectations(t)
804         ps.AssertExpectations(t)
805 }
806
807 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
808         ps, r, db := setup(true)
809         ch := make(chan *redis.Message)
810         msg := redis.Message{
811                 Channel: "{prefix}channel",
812                 Pattern: "pattern",
813                 Payload: "event",
814         }
815         ps.On("Channel").Return(ch)
816         ps.On("Unsubscribe").Return(nil)
817         ps.On("Close").Return(nil)
818         count := 0
819         receivedChannel := ""
820
821         db.SubscribeChannelDB(func(channel string, payload ...string) {
822                 count++
823                 receivedChannel = channel
824         }, "{prefix}", "---", "{prefix}channel")
825         ch <- &msg
826         db.UnsubscribeChannelDB("{prefix}channel")
827         time.Sleep(1 * time.Second)
828
829         db.SubscribeChannelDB(func(channel string, payload ...string) {
830                 count++
831                 receivedChannel = channel
832         }, "{prefix}", "---", "{prefix}channel")
833         ch <- &msg
834         db.UnsubscribeChannelDB("{prefix}channel")
835
836         time.Sleep(1 * time.Second)
837         assert.Equal(t, 2, count)
838         assert.Equal(t, "channel", receivedChannel)
839         r.AssertExpectations(t)
840         ps.AssertExpectations(t)
841 }
842
843 func TestPTTLSuccessfully(t *testing.T) {
844         _, r, db := setup(true)
845         expectedKey := "key"
846         expectedResult := time.Duration(1)
847         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
848                 nil))
849         result, err := db.PTTL("key")
850         assert.Equal(t, result, expectedResult)
851         assert.Nil(t, err)
852         r.AssertExpectations(t)
853 }
854
855 func TestPTTLFailure(t *testing.T) {
856         _, r, db := setup(true)
857         expectedKey := "key"
858         expectedResult := time.Duration(1)
859         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
860                 errors.New("Some error")))
861         result, err := db.PTTL("key")
862         assert.Equal(t, result, expectedResult)
863         assert.NotNil(t, err)
864         r.AssertExpectations(t)
865 }
866
867 func TestPExpireIESuccessfully(t *testing.T) {
868         _, r, db := setup(true)
869         expectedKey := "key"
870         expectedData := "data"
871         expectedDuration := strconv.FormatInt(int64(10000), 10)
872
873         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
874                 Return(redis.NewCmdResult(int64(1), nil))
875
876         err := db.PExpireIE("key", "data", 10*time.Second)
877         assert.Nil(t, err)
878         r.AssertExpectations(t)
879 }
880
881 func TestPExpireIEFailure(t *testing.T) {
882         _, r, db := setup(true)
883         expectedKey := "key"
884         expectedData := "data"
885         expectedDuration := strconv.FormatInt(int64(10000), 10)
886
887         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
888                 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
889
890         err := db.PExpireIE("key", "data", 10*time.Second)
891         assert.NotNil(t, err)
892         r.AssertExpectations(t)
893 }
894
895 func TestPExpireIELockNotHeld(t *testing.T) {
896         _, r, db := setup(true)
897         expectedKey := "key"
898         expectedData := "data"
899         expectedDuration := strconv.FormatInt(int64(10000), 10)
900
901         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
902                 Return(redis.NewCmdResult(int64(0), nil))
903
904         err := db.PExpireIE("key", "data", 10*time.Second)
905         assert.NotNil(t, err)
906         r.AssertExpectations(t)
907 }
908
909 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
910         rcls, dbs := setupEnv(
911                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "",
912         )
913         assert.Equal(t, 1, len(rcls))
914         assert.Equal(t, 1, len(dbs))
915
916         expectedKeysAndValues := []interface{}{"key1", "value1"}
917         rcls[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
918         err := dbs[0].MSet("key1", "value1")
919         assert.Nil(t, err)
920         rcls[0].AssertExpectations(t)
921 }
922
923 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
924         rcls, dbs := setupEnv(
925                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "",
926         )
927         assert.Equal(t, 1, len(rcls))
928         assert.Equal(t, 1, len(dbs))
929
930         expectedKeysAndValues := []interface{}{"key1", "value1"}
931         rcls[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
932         err := dbs[0].MSet("key1", "value1")
933         assert.Nil(t, err)
934         rcls[0].AssertExpectations(t)
935 }
936
937 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
938         rcls, dbs := setupEnv(
939                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
940                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt",
941         )
942         assert.Equal(t, 2, len(rcls))
943         assert.Equal(t, 2, len(dbs))
944
945         expectedKeysAndValues := []interface{}{"key1", "value1"}
946         rcls[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
947         err := dbs[0].MSet("key1", "value1")
948         assert.Nil(t, err)
949         rcls[0].AssertExpectations(t)
950
951         expectedKeysAndValues = []interface{}{"key2", "value2"}
952         rcls[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
953         err = dbs[1].MSet("key2", "value2")
954         assert.Nil(t, err)
955         rcls[0].AssertExpectations(t)
956         rcls[1].AssertExpectations(t)
957 }
958
959 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
960         rcls, dbs := setupEnv(
961                 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
962                 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt",
963         )
964         assert.Equal(t, 2, len(rcls))
965         assert.Equal(t, 2, len(dbs))
966
967         expectedKeysAndValues := []interface{}{"key1", "value1"}
968         rcls[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
969         err := dbs[0].MSet("key1", "value1")
970         assert.Nil(t, err)
971         rcls[0].AssertExpectations(t)
972
973         expectedKeysAndValues = []interface{}{"key2", "value2"}
974         rcls[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
975         err = dbs[1].MSet("key2", "value2")
976         assert.Nil(t, err)
977         rcls[0].AssertExpectations(t)
978         rcls[1].AssertExpectations(t)
979 }