Add resource locking
[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 package sdlgoredis_test
19
20 import (
21         "errors"
22         "strconv"
23         "testing"
24         "time"
25
26         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
27         "github.com/go-redis/redis"
28         "github.com/stretchr/testify/assert"
29         "github.com/stretchr/testify/mock"
30 )
31
32 type clientMock struct {
33         mock.Mock
34 }
35
36 type pubSubMock struct {
37         mock.Mock
38 }
39
40 func (m *pubSubMock) Channel() <-chan *redis.Message {
41         return m.Called().Get(0).(chan *redis.Message)
42 }
43
44 func (m *pubSubMock) Subscribe(channels ...string) error {
45         return m.Called().Error(0)
46 }
47
48 func (m *pubSubMock) Unsubscribe(channels ...string) error {
49         return m.Called().Error(0)
50 }
51
52 func (m *pubSubMock) Close() error {
53         return m.Called().Error(0)
54 }
55
56 func (m *clientMock) Command() *redis.CommandsInfoCmd {
57         return m.Called().Get(0).(*redis.CommandsInfoCmd)
58 }
59
60 func (m *clientMock) Close() error {
61         return m.Called().Error(0)
62 }
63
64 func (m *clientMock) Subscribe(channels ...string) *redis.PubSub {
65         return m.Called(channels).Get(0).(*redis.PubSub)
66 }
67
68 func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
69         return m.Called(pairs).Get(0).(*redis.StatusCmd)
70 }
71
72 func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
73         return m.Called(args).Get(0).(*redis.Cmd)
74 }
75
76 func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
77         return m.Called(keys).Get(0).(*redis.SliceCmd)
78 }
79
80 func (m *clientMock) Del(keys ...string) *redis.IntCmd {
81         return m.Called(keys).Get(0).(*redis.IntCmd)
82 }
83
84 func (m *clientMock) Keys(pattern string) *redis.StringSliceCmd {
85         return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
86 }
87
88 func (m *clientMock) SetNX(key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
89         return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
90 }
91
92 func (m *clientMock) SAdd(key string, members ...interface{}) *redis.IntCmd {
93         return m.Called(key, members).Get(0).(*redis.IntCmd)
94 }
95
96 func (m *clientMock) SRem(key string, members ...interface{}) *redis.IntCmd {
97         return m.Called(key, members).Get(0).(*redis.IntCmd)
98 }
99
100 func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
101         return m.Called(key).Get(0).(*redis.StringSliceCmd)
102 }
103
104 func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
105         return m.Called(key, member).Get(0).(*redis.BoolCmd)
106 }
107
108 func (m *clientMock) SCard(key string) *redis.IntCmd {
109         return m.Called(key).Get(0).(*redis.IntCmd)
110 }
111
112 func (m *clientMock) PTTL(key string) *redis.DurationCmd {
113         return m.Called(key).Get(0).(*redis.DurationCmd)
114 }
115
116 func (m *clientMock) Eval(script string, keys []string, args ...interface{}) *redis.Cmd {
117         return m.Called(script, keys).Get(0).(*redis.Cmd)
118 }
119
120 func (m *clientMock) EvalSha(sha1 string, keys []string, args ...interface{}) *redis.Cmd {
121         return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
122 }
123
124 func (m *clientMock) ScriptExists(scripts ...string) *redis.BoolSliceCmd {
125         return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
126 }
127
128 func (m *clientMock) ScriptLoad(script string) *redis.StringCmd {
129         return m.Called(script).Get(0).(*redis.StringCmd)
130 }
131
132 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
133         mock := new(pubSubMock)
134         return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
135                 return mock
136         }
137 }
138
139 func setup(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
140         mock := new(clientMock)
141         pubSubMock, subscribeNotifications := setSubscribeNotifications()
142         db := sdlgoredis.CreateDB(mock, subscribeNotifications)
143
144         dummyCommandInfo := redis.CommandInfo{
145                 Name: "dummy",
146         }
147         cmdResult := make(map[string]*redis.CommandInfo, 0)
148
149         if commandsExists {
150                 cmdResult = map[string]*redis.CommandInfo{
151                         "setie":    &dummyCommandInfo,
152                         "delie":    &dummyCommandInfo,
153                         "setiepub": &dummyCommandInfo,
154                         "setnxpub": &dummyCommandInfo,
155                         "msetmpub": &dummyCommandInfo,
156                         "delmpub":  &dummyCommandInfo,
157                 }
158         } else {
159                 cmdResult = map[string]*redis.CommandInfo{
160                         "dummy": &dummyCommandInfo,
161                 }
162         }
163
164         mock.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
165         db.CheckCommands()
166         return pubSubMock, mock, db
167 }
168
169 func TestMSetSuccessfully(t *testing.T) {
170         _, r, db := setup(true)
171         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
172         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
173         err := db.MSet("key1", "value1", "key2", 2)
174         assert.Nil(t, err)
175         r.AssertExpectations(t)
176 }
177
178 func TestMSetFailure(t *testing.T) {
179         _, r, db := setup(true)
180         expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
181         r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
182         err := db.MSet("key1", "value1", "key2", 2)
183         assert.NotNil(t, err)
184         r.AssertExpectations(t)
185 }
186
187 func TestMSetMPubSuccessfully(t *testing.T) {
188         _, r, db := setup(true)
189         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
190                 "chan1", "event1", "chan2", "event2"}
191         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
192         assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
193                 "key1", "val1", "key2", "val2"))
194         r.AssertExpectations(t)
195 }
196
197 func TestMsetMPubFailure(t *testing.T) {
198         _, r, db := setup(true)
199         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
200                 "chan1", "event1", "chan2", "event2"}
201         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
202         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
203                 "key1", "val1", "key2", "val2"))
204         r.AssertExpectations(t)
205 }
206
207 func TestMSetMPubCommandMissing(t *testing.T) {
208         _, r, db := setup(false)
209         expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
210                 "chan1", "event1", "chan2", "event2"}
211         r.AssertNotCalled(t, "Do", expectedMessage)
212         assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
213                 "key1", "val1", "key2", "val2"))
214         r.AssertExpectations(t)
215
216 }
217
218 func TestMGetSuccessfully(t *testing.T) {
219         _, r, db := setup(true)
220         expectedKeys := []string{"key1", "key2", "key3"}
221         expectedResult := []interface{}{"val1", 2, nil}
222         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
223         result, err := db.MGet([]string{"key1", "key2", "key3"})
224         assert.Equal(t, result, expectedResult)
225         assert.Nil(t, err)
226         r.AssertExpectations(t)
227 }
228
229 func TestMGetFailure(t *testing.T) {
230         _, r, db := setup(true)
231         expectedKeys := []string{"key1", "key2", "key3"}
232         expectedResult := []interface{}{nil}
233         r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
234                 errors.New("Some error")))
235         result, err := db.MGet([]string{"key1", "key2", "key3"})
236         assert.Equal(t, result, expectedResult)
237         assert.NotNil(t, err)
238         r.AssertExpectations(t)
239 }
240
241 func TestDelMPubSuccessfully(t *testing.T) {
242         _, r, db := setup(true)
243         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
244                 "chan2", "event2"}
245         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
246         assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
247                 []string{"key1", "key2"}))
248         r.AssertExpectations(t)
249 }
250
251 func TestDelMPubFailure(t *testing.T) {
252         _, r, db := setup(true)
253         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
254                 "chan2", "event2"}
255         r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
256         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
257                 []string{"key1", "key2"}))
258         r.AssertExpectations(t)
259 }
260
261 func TestDelMPubCommandMissing(t *testing.T) {
262         _, r, db := setup(false)
263         expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
264                 "chan2", "event2"}
265         r.AssertNotCalled(t, "Do", expectedMessage)
266         assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
267                 []string{"key1", "key2"}))
268         r.AssertExpectations(t)
269 }
270
271 func TestDelSuccessfully(t *testing.T) {
272         _, r, db := setup(true)
273         expectedKeys := []string{"key1", "key2"}
274         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
275         assert.Nil(t, db.Del([]string{"key1", "key2"}))
276         r.AssertExpectations(t)
277 }
278
279 func TestDelFailure(t *testing.T) {
280         _, r, db := setup(true)
281         expectedKeys := []string{"key1", "key2"}
282         r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
283         assert.NotNil(t, db.Del([]string{"key1", "key2"}))
284         r.AssertExpectations(t)
285 }
286
287 func TestKeysSuccessfully(t *testing.T) {
288         _, r, db := setup(true)
289         expectedPattern := "pattern*"
290         expectedResult := []string{"pattern1", "pattern2"}
291         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
292         result, err := db.Keys("pattern*")
293         assert.Equal(t, result, expectedResult)
294         assert.Nil(t, err)
295         r.AssertExpectations(t)
296 }
297
298 func TestKeysFailure(t *testing.T) {
299         _, r, db := setup(true)
300         expectedPattern := "pattern*"
301         expectedResult := []string{}
302         r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
303                 errors.New("Some error")))
304         _, err := db.Keys("pattern*")
305         assert.NotNil(t, err)
306         r.AssertExpectations(t)
307 }
308
309 func TestSetIEKeyExists(t *testing.T) {
310         _, r, db := setup(true)
311         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
312         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
313         result, err := db.SetIE("key", "olddata", "newdata")
314         assert.True(t, result)
315         assert.Nil(t, err)
316         r.AssertExpectations(t)
317 }
318
319 func TestSetIEKeyDoesntExists(t *testing.T) {
320         _, r, db := setup(true)
321         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
322         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
323         result, err := db.SetIE("key", "olddata", "newdata")
324         assert.False(t, result)
325         assert.Nil(t, err)
326         r.AssertExpectations(t)
327 }
328
329 func TestSetIEFailure(t *testing.T) {
330         _, r, db := setup(true)
331         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
332         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
333         result, err := db.SetIE("key", "olddata", "newdata")
334         assert.False(t, result)
335         assert.NotNil(t, err)
336         r.AssertExpectations(t)
337 }
338
339 func TestSetIECommandMissing(t *testing.T) {
340         _, r, db := setup(false)
341         expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
342         r.AssertNotCalled(t, "Do", expectedMessage)
343         result, err := db.SetIE("key", "olddata", "newdata")
344         assert.False(t, result)
345         assert.NotNil(t, err)
346         r.AssertExpectations(t)
347 }
348
349 func TestSetIEPubKeyExists(t *testing.T) {
350         _, r, db := setup(true)
351         expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
352         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
353         result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
354         assert.True(t, result)
355         assert.Nil(t, err)
356         r.AssertExpectations(t)
357 }
358
359 func TestSetIEPubKeyDoesntExists(t *testing.T) {
360         _, r, db := setup(true)
361         expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
362         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
363         result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
364         assert.False(t, result)
365         assert.Nil(t, err)
366         r.AssertExpectations(t)
367 }
368
369 func TestSetIEPubFailure(t *testing.T) {
370         _, r, db := setup(true)
371         expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
372         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
373         result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
374         assert.False(t, result)
375         assert.NotNil(t, err)
376         r.AssertExpectations(t)
377 }
378
379 func TestSetIEPubCommandMissing(t *testing.T) {
380         _, r, db := setup(false)
381         expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
382         r.AssertNotCalled(t, "Do", expectedMessage)
383         result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
384         assert.False(t, result)
385         assert.NotNil(t, err)
386         r.AssertExpectations(t)
387 }
388
389 func TestSetNXPubKeyDoesntExist(t *testing.T) {
390         _, r, db := setup(true)
391         expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
392         r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
393         result, err := db.SetNXPub("channel", "message", "key", "data")
394         assert.True(t, result)
395         assert.Nil(t, err)
396         r.AssertExpectations(t)
397 }
398
399 func TestSetNXPubKeyExists(t *testing.T) {
400         _, r, db := setup(true)
401         expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
402         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
403         result, err := db.SetNXPub("channel", "message", "key", "data")
404         assert.False(t, result)
405         assert.Nil(t, err)
406         r.AssertExpectations(t)
407 }
408
409 func TestSetNXPubFailure(t *testing.T) {
410         _, r, db := setup(true)
411         expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
412         r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
413         result, err := db.SetNXPub("channel", "message", "key", "data")
414         assert.False(t, result)
415         assert.NotNil(t, err)
416         r.AssertExpectations(t)
417 }
418
419 func TestSetNXPubCommandMissing(t *testing.T) {
420         _, r, db := setup(false)
421         expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
422         r.AssertNotCalled(t, "Do", expectedMessage)
423         result, err := db.SetNXPub("channel", "message", "key", "data")
424         assert.False(t, result)
425         assert.NotNil(t, err)
426         r.AssertExpectations(t)
427 }
428
429 func TestSetNXSuccessfully(t *testing.T) {
430         _, r, db := setup(true)
431         expectedKey := "key"
432         expectedData := "data"
433         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
434         result, err := db.SetNX("key", "data", 0)
435         assert.True(t, result)
436         assert.Nil(t, err)
437         r.AssertExpectations(t)
438 }
439
440 func TestSetNXUnsuccessfully(t *testing.T) {
441         _, r, db := setup(true)
442         expectedKey := "key"
443         expectedData := "data"
444         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
445         result, err := db.SetNX("key", "data", 0)
446         assert.False(t, result)
447         assert.Nil(t, err)
448         r.AssertExpectations(t)
449 }
450
451 func TestSetNXFailure(t *testing.T) {
452         _, r, db := setup(true)
453         expectedKey := "key"
454         expectedData := "data"
455         r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
456                 Return(redis.NewBoolResult(false, errors.New("Some error")))
457         result, err := db.SetNX("key", "data", 0)
458         assert.False(t, result)
459         assert.NotNil(t, err)
460         r.AssertExpectations(t)
461 }
462
463 func TestDelIEPubKeyDoesntExist(t *testing.T) {
464         _, r, db := setup(true)
465         expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
466         r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, nil))
467         result, err := db.DelIEPub("channel", "message", "key", "data")
468         assert.False(t, result)
469         assert.Nil(t, err)
470         r.AssertExpectations(t)
471 }
472
473 func TestDelIEPubKeyExists(t *testing.T) {
474         _, r, db := setup(true)
475         expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
476         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
477         result, err := db.DelIEPub("channel", "message", "key", "data")
478         assert.True(t, result)
479         assert.Nil(t, err)
480         r.AssertExpectations(t)
481 }
482
483 func TestDelIEPubFailure(t *testing.T) {
484         _, r, db := setup(true)
485         expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
486         r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, errors.New("Some error")))
487         result, err := db.DelIEPub("channel", "message", "key", "data")
488         assert.False(t, result)
489         assert.NotNil(t, err)
490         r.AssertExpectations(t)
491 }
492
493 func TestDelIEPubCommandMissing(t *testing.T) {
494         _, r, db := setup(false)
495         expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
496         r.AssertNotCalled(t, "Do", expectedMessage)
497         result, err := db.DelIEPub("channel", "message", "key", "data")
498         assert.False(t, result)
499         assert.NotNil(t, err)
500         r.AssertExpectations(t)
501 }
502
503 func TestDelIEKeyDoesntExist(t *testing.T) {
504         _, r, db := setup(true)
505         expectedMessage := []interface{}{"DELIE", "key", "data"}
506         r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, nil))
507         result, err := db.DelIE("key", "data")
508         assert.False(t, result)
509         assert.Nil(t, err)
510         r.AssertExpectations(t)
511 }
512
513 func TestDelIEKeyExists(t *testing.T) {
514         _, r, db := setup(true)
515         expectedMessage := []interface{}{"DELIE", "key", "data"}
516         r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
517         result, err := db.DelIE("key", "data")
518         assert.True(t, result)
519         assert.Nil(t, err)
520         r.AssertExpectations(t)
521 }
522
523 func TestDelIEFailure(t *testing.T) {
524         _, r, db := setup(true)
525         expectedMessage := []interface{}{"DELIE", "key", "data"}
526         r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, errors.New("Some error")))
527         result, err := db.DelIE("key", "data")
528         assert.False(t, result)
529         assert.NotNil(t, err)
530         r.AssertExpectations(t)
531 }
532
533 func TestDelIECommandMissing(t *testing.T) {
534         _, r, db := setup(false)
535         expectedMessage := []interface{}{"DELIE", "key", "data"}
536         r.AssertNotCalled(t, "Do", expectedMessage)
537         result, err := db.DelIE("key", "data")
538         assert.False(t, result)
539         assert.NotNil(t, err)
540         r.AssertExpectations(t)
541 }
542
543 func TestSAddSuccessfully(t *testing.T) {
544         _, r, db := setup(true)
545         expectedKey := "key"
546         expectedData := []interface{}{"data", 2}
547         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
548         assert.Nil(t, db.SAdd("key", "data", 2))
549         r.AssertExpectations(t)
550 }
551
552 func TestSAddFailure(t *testing.T) {
553         _, r, db := setup(true)
554         expectedKey := "key"
555         expectedData := []interface{}{"data", 2}
556         r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
557         assert.NotNil(t, db.SAdd("key", "data", 2))
558         r.AssertExpectations(t)
559 }
560
561 func TestSRemSuccessfully(t *testing.T) {
562         _, r, db := setup(true)
563         expectedKey := "key"
564         expectedData := []interface{}{"data", 2}
565         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
566         assert.Nil(t, db.SRem("key", "data", 2))
567         r.AssertExpectations(t)
568 }
569
570 func TestSRemFailure(t *testing.T) {
571         _, r, db := setup(true)
572         expectedKey := "key"
573         expectedData := []interface{}{"data", 2}
574         r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
575         assert.NotNil(t, db.SRem("key", "data", 2))
576         r.AssertExpectations(t)
577 }
578
579 func TestSMembersSuccessfully(t *testing.T) {
580         _, r, db := setup(true)
581         expectedKey := "key"
582         expectedResult := []string{"member1", "member2"}
583         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
584         result, err := db.SMembers("key")
585         assert.Equal(t, result, expectedResult)
586         assert.Nil(t, err)
587         r.AssertExpectations(t)
588 }
589
590 func TestSMembersFailure(t *testing.T) {
591         _, r, db := setup(true)
592         expectedKey := "key"
593         expectedResult := []string{"member1", "member2"}
594         r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
595                 errors.New("Some error")))
596         result, err := db.SMembers("key")
597         assert.Equal(t, result, expectedResult)
598         assert.NotNil(t, err)
599         r.AssertExpectations(t)
600 }
601
602 func TestSIsMemberIsMember(t *testing.T) {
603         _, r, db := setup(true)
604         expectedKey := "key"
605         expectedData := "data"
606         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
607         result, err := db.SIsMember("key", "data")
608         assert.True(t, result)
609         assert.Nil(t, err)
610         r.AssertExpectations(t)
611 }
612
613 func TestSIsMemberIsNotMember(t *testing.T) {
614         _, r, db := setup(true)
615         expectedKey := "key"
616         expectedData := "data"
617         r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
618         result, err := db.SIsMember("key", "data")
619         assert.False(t, result)
620         assert.Nil(t, err)
621         r.AssertExpectations(t)
622 }
623
624 func TestSIsMemberFailure(t *testing.T) {
625         _, r, db := setup(true)
626         expectedKey := "key"
627         expectedData := "data"
628         r.On("SIsMember", expectedKey, expectedData).
629                 Return(redis.NewBoolResult(false, errors.New("Some error")))
630         result, err := db.SIsMember("key", "data")
631         assert.False(t, result)
632         assert.NotNil(t, err)
633         r.AssertExpectations(t)
634 }
635
636 func TestSCardSuccessfully(t *testing.T) {
637         _, r, db := setup(true)
638         expectedKey := "key"
639         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
640         result, err := db.SCard("key")
641         assert.Equal(t, int64(1), result)
642         assert.Nil(t, err)
643         r.AssertExpectations(t)
644 }
645
646 func TestSCardFailure(t *testing.T) {
647         _, r, db := setup(true)
648         expectedKey := "key"
649         r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
650         result, err := db.SCard("key")
651         assert.Equal(t, int64(1), result)
652         assert.NotNil(t, err)
653         r.AssertExpectations(t)
654 }
655
656 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
657         ps, r, db := setup(true)
658         ch := make(chan *redis.Message)
659         msg := redis.Message{
660                 Channel: "{prefix}channel",
661                 Pattern: "pattern",
662                 Payload: "event",
663         }
664         ps.On("Channel").Return(ch)
665         ps.On("Unsubscribe").Return(nil)
666         ps.On("Close").Return(nil)
667         count := 0
668         receivedChannel := ""
669         db.SubscribeChannelDB(func(channel string, payload ...string) {
670                 count++
671                 receivedChannel = channel
672         }, "{prefix}", "---", "{prefix}channel")
673         ch <- &msg
674         db.UnsubscribeChannelDB("{prefix}channel")
675         time.Sleep(1 * time.Second)
676         assert.Equal(t, 1, count)
677         assert.Equal(t, "channel", receivedChannel)
678         r.AssertExpectations(t)
679         ps.AssertExpectations(t)
680 }
681
682 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
683         ps, r, db := setup(true)
684         ch := make(chan *redis.Message)
685         msg1 := redis.Message{
686                 Channel: "{prefix}channel1",
687                 Pattern: "pattern",
688                 Payload: "event",
689         }
690         msg2 := redis.Message{
691                 Channel: "{prefix}channel2",
692                 Pattern: "pattern",
693                 Payload: "event",
694         }
695         ps.On("Channel").Return(ch)
696         ps.On("Subscribe").Return(nil)
697         ps.On("Unsubscribe").Return(nil)
698         ps.On("Unsubscribe").Return(nil)
699         ps.On("Close").Return(nil)
700         count := 0
701         receivedChannel1 := ""
702         db.SubscribeChannelDB(func(channel string, payload ...string) {
703                 count++
704                 receivedChannel1 = channel
705         }, "{prefix}", "---", "{prefix}channel1")
706         ch <- &msg1
707         receivedChannel2 := ""
708         db.SubscribeChannelDB(func(channel string, payload ...string) {
709                 count++
710                 receivedChannel2 = channel
711         }, "{prefix}", "---", "{prefix}channel2")
712
713         db.UnsubscribeChannelDB("{prefix}channel1")
714         ch <- &msg2
715         db.UnsubscribeChannelDB("{prefix}channel2")
716         time.Sleep(1 * time.Second)
717         assert.Equal(t, 2, count)
718         assert.Equal(t, "channel1", receivedChannel1)
719         assert.Equal(t, "channel2", receivedChannel2)
720         r.AssertExpectations(t)
721         ps.AssertExpectations(t)
722 }
723
724 func TestPTTLSuccessfully(t *testing.T) {
725         _, r, db := setup(true)
726         expectedKey := "key"
727         expectedResult := time.Duration(1)
728         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
729                 nil))
730         result, err := db.PTTL("key")
731         assert.Equal(t, result, expectedResult)
732         assert.Nil(t, err)
733         r.AssertExpectations(t)
734 }
735
736 func TestPTTLFailure(t *testing.T) {
737         _, r, db := setup(true)
738         expectedKey := "key"
739         expectedResult := time.Duration(1)
740         r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
741                 errors.New("Some error")))
742         result, err := db.PTTL("key")
743         assert.Equal(t, result, expectedResult)
744         assert.NotNil(t, err)
745         r.AssertExpectations(t)
746 }
747
748 func TestPExpireIESuccessfully(t *testing.T) {
749         _, r, db := setup(true)
750         expectedKey := "key"
751         expectedData := "data"
752         expectedDuration := strconv.FormatInt(int64(10000), 10)
753
754         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
755                 Return(redis.NewCmdResult(int64(1), nil))
756
757         err := db.PExpireIE("key", "data", 10*time.Second)
758         assert.Nil(t, err)
759         r.AssertExpectations(t)
760 }
761
762 func TestPExpireIEFailure(t *testing.T) {
763         _, r, db := setup(true)
764         expectedKey := "key"
765         expectedData := "data"
766         expectedDuration := strconv.FormatInt(int64(10000), 10)
767
768         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
769                 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
770
771         err := db.PExpireIE("key", "data", 10*time.Second)
772         assert.NotNil(t, err)
773         r.AssertExpectations(t)
774 }
775
776 func TestPExpireIELockNotHeld(t *testing.T) {
777         _, r, db := setup(true)
778         expectedKey := "key"
779         expectedData := "data"
780         expectedDuration := strconv.FormatInt(int64(10000), 10)
781
782         r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
783                 Return(redis.NewCmdResult(int64(0), nil))
784
785         err := db.PExpireIE("key", "data", 10*time.Second)
786         assert.NotNil(t, err)
787         r.AssertExpectations(t)
788 }