2 Copyright (c) 2019 AT&T Intellectual Property.
3 Copyright (c) 2018-2019 Nokia.
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
9 http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
23 package sdlgoredis_test
28 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
29 "github.com/go-redis/redis/v8"
30 "github.com/stretchr/testify/assert"
31 "github.com/stretchr/testify/mock"
37 type clientMock struct {
41 type pubSubMock struct {
49 func (m *pubSubMock) Channel(opts ...redis.ChannelOption) <-chan *redis.Message {
50 return m.Called().Get(0).(chan *redis.Message)
53 func (m *pubSubMock) Subscribe(ctx context.Context, channels ...string) error {
54 return m.Called().Error(0)
57 func (m *pubSubMock) Unsubscribe(ctx context.Context, channels ...string) error {
58 return m.Called().Error(0)
61 func (m *pubSubMock) Close() error {
62 return m.Called().Error(0)
65 func (m *clientMock) Command(ctx context.Context) *redis.CommandsInfoCmd {
66 return m.Called().Get(0).(*redis.CommandsInfoCmd)
69 func (m *clientMock) Close() error {
70 return m.Called().Error(0)
73 func (m *clientMock) Subscribe(ctx context.Context, channels ...string) *redis.PubSub {
74 return m.Called(channels).Get(0).(*redis.PubSub)
77 func (m *clientMock) MSet(ctx context.Context, pairs ...interface{}) *redis.StatusCmd {
78 return m.Called(pairs).Get(0).(*redis.StatusCmd)
81 func (m *clientMock) Do(ctx context.Context, args ...interface{}) *redis.Cmd {
82 return m.Called(args).Get(0).(*redis.Cmd)
85 func (m *clientMock) MGet(ctx context.Context, keys ...string) *redis.SliceCmd {
86 return m.Called(keys).Get(0).(*redis.SliceCmd)
89 func (m *clientMock) Del(ctx context.Context, keys ...string) *redis.IntCmd {
90 return m.Called(keys).Get(0).(*redis.IntCmd)
93 func (m *clientMock) Keys(ctx context.Context, pattern string) *redis.StringSliceCmd {
94 return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
97 func (m *clientMock) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
98 return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
101 func (m *clientMock) SAdd(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
102 return m.Called(key, members).Get(0).(*redis.IntCmd)
105 func (m *clientMock) SRem(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
106 return m.Called(key, members).Get(0).(*redis.IntCmd)
109 func (m *clientMock) SMembers(ctx context.Context, key string) *redis.StringSliceCmd {
110 return m.Called(key).Get(0).(*redis.StringSliceCmd)
113 func (m *clientMock) SIsMember(ctx context.Context, key string, member interface{}) *redis.BoolCmd {
114 return m.Called(key, member).Get(0).(*redis.BoolCmd)
117 func (m *clientMock) SCard(ctx context.Context, key string) *redis.IntCmd {
118 return m.Called(key).Get(0).(*redis.IntCmd)
121 func (m *clientMock) PTTL(ctx context.Context, key string) *redis.DurationCmd {
122 return m.Called(key).Get(0).(*redis.DurationCmd)
125 func (m *clientMock) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd {
126 return m.Called(script, keys).Get(0).(*redis.Cmd)
129 func (m *clientMock) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd {
130 return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
133 func (m *clientMock) ScriptExists(ctx context.Context, scripts ...string) *redis.BoolSliceCmd {
134 return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
137 func (m *clientMock) ScriptLoad(ctx context.Context, script string) *redis.StringCmd {
138 return m.Called(script).Get(0).(*redis.StringCmd)
141 func (m *clientMock) Info(ctx context.Context, section ...string) *redis.StringCmd {
142 return m.Called(section).Get(0).(*redis.StringCmd)
145 type MockRedisSentinel struct {
149 func (m *MockRedisSentinel) Master(ctx context.Context, name string) *redis.StringStringMapCmd {
151 return a.Get(0).(*redis.StringStringMapCmd)
154 func (m *MockRedisSentinel) Slaves(ctx context.Context, name string) *redis.SliceCmd {
156 return a.Get(0).(*redis.SliceCmd)
159 func (m *MockRedisSentinel) Sentinels(ctx context.Context, name string) *redis.SliceCmd {
161 return a.Get(0).(*redis.SliceCmd)
164 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
165 mock := new(pubSubMock)
166 return mock, func(ctx context.Context, client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
171 func (m *MockOS) Getenv(key string, defValue string) string {
172 a := m.Called(key, defValue)
176 type setupEv struct {
177 pubSubMock []*pubSubMock
178 rClient []*clientMock
179 rSentinel []*MockRedisSentinel
183 func setupHaEnv(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
184 psm, cm, _, db := setupHaEnvWithSentinels(commandsExists, "3")
188 func setupHaEnvWithSentinels(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, []*MockRedisSentinel, *sdlgoredis.DB) {
189 setupVals := setupEnv(
191 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
198 return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.rSentinel, setupVals.db[0]
201 func setupSingleEnv(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
202 setupVals := setupEnv(
204 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
205 "6376", "", "", "", nodeCnt,
207 return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
210 func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nodeCnt string) setupEv {
213 dummyCommandInfo := redis.CommandInfo{
217 cmdResult := make(map[string]*redis.CommandInfo, 0)
219 cmdResult = map[string]*redis.CommandInfo{
220 "setie": &dummyCommandInfo,
221 "delie": &dummyCommandInfo,
222 "setiepub": &dummyCommandInfo,
223 "setnxpub": &dummyCommandInfo,
224 "msetmpub": &dummyCommandInfo,
225 "delmpub": &dummyCommandInfo,
228 cmdResult = map[string]*redis.CommandInfo{
229 "dummy": &dummyCommandInfo,
233 osmock := new(MockOS)
234 osmock.On("Getenv", "DBAAS_SERVICE_HOST", "localhost").Return(host)
235 osmock.On("Getenv", "DBAAS_SERVICE_PORT", "6379").Return(port)
236 osmock.On("Getenv", "DBAAS_MASTER_NAME", "").Return(msname)
237 osmock.On("Getenv", "DBAAS_SERVICE_SENTINEL_PORT", "").Return(sntport)
238 osmock.On("Getenv", "DBAAS_CLUSTER_ADDR_LIST", "").Return(clsaddrlist)
239 osmock.On("Getenv", "DBAAS_NODE_COUNT", "1").Return(nodeCnt)
241 pubSubMock, subscribeNotifications := setSubscribeNotifications()
242 smock := new(MockRedisSentinel)
243 ret.rSentinel = append(ret.rSentinel, smock)
244 clients := sdlgoredis.ReadConfigAndCreateDbClients(
246 func(addr, port, clusterName string, isHa bool) sdlgoredis.RedisClient {
247 clm := new(clientMock)
248 clm.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
249 ret.rClient = append(ret.rClient, clm)
250 ret.pubSubMock = append(ret.pubSubMock, pubSubMock)
253 subscribeNotifications,
254 func(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
255 s := &sdlgoredis.Sentinel{
256 IredisSentinelClient: smock,
266 func newMockRedisMasterCallResp(role, ip, port, flag string) map[string]string {
267 resp := map[string]string{}
269 resp["role-reported"] = role
277 type mockRedisSlaves struct {
281 func newMockRedisSlavesCall() *mockRedisSlaves {
282 return new(mockRedisSlaves)
285 func (mrr *mockRedisSlaves) add(role, ip, port, link, flag string) {
286 mrr.resp = append(mrr.resp,
288 "role-reported", role,
291 "master-link-status", link,
297 type mockRedisSentinels struct {
301 func newMockRedisSentinelsCall() *mockRedisSentinels {
302 return new(mockRedisSentinels)
305 func (mrs *mockRedisSentinels) add(ip, port, flag string) {
306 mrs.resp = append(mrs.resp,
315 type ExpDbState struct {
319 func newExpDbState(nodeCnt int, err error) *ExpDbState {
320 state := new(ExpDbState)
321 state.s.ConfigNodeCnt = nodeCnt
326 func (edbs *ExpDbState) addPrimary(role, ip, port, flag string, err error) {
327 edbs.s.PrimaryDbState.Err = err
328 edbs.s.PrimaryDbState.Fields = sdlgoredis.PrimaryDbStateFields{
336 func (edbs *ExpDbState) addReplica(role, ip, port, link, flag string, err error) {
337 if edbs.s.ReplicasDbState == nil {
338 edbs.s.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
339 edbs.s.ReplicasDbState.States = make([]*sdlgoredis.ReplicaDbState, 0)
341 edbs.s.ReplicasDbState.Err = err
342 if ip != "" || port != "" || link != "" || flag != "" {
343 edbs.s.ReplicasDbState.States = append(edbs.s.ReplicasDbState.States,
344 &sdlgoredis.ReplicaDbState{
345 Fields: sdlgoredis.ReplicaDbStateFields{
349 PrimaryLinkStatus: link,
357 func (edbs *ExpDbState) addSentinel(ip, port, flag string, err error) {
358 if edbs.s.SentinelsDbState == nil {
359 edbs.s.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
360 edbs.s.SentinelsDbState.States = make([]*sdlgoredis.SentinelDbState, 0)
362 edbs.s.SentinelsDbState.Err = err
363 if ip != "" || port != "" || flag != "" {
364 edbs.s.SentinelsDbState.States = append(edbs.s.SentinelsDbState.States,
365 &sdlgoredis.SentinelDbState{
366 Fields: sdlgoredis.SentinelDbStateFields{
376 func TestCloseDbSuccessfully(t *testing.T) {
377 _, r, db := setupHaEnv(true)
378 r.On("Close").Return(nil)
381 r.AssertExpectations(t)
384 func TestCloseDbFailure(t *testing.T) {
385 _, r, db := setupHaEnv(true)
386 r.On("Close").Return(errors.New("Some error"))
388 assert.NotNil(t, err)
389 r.AssertExpectations(t)
392 func TestMSetSuccessfully(t *testing.T) {
393 _, r, db := setupHaEnv(true)
394 expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
395 r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
396 err := db.MSet("key1", "value1", "key2", 2)
398 r.AssertExpectations(t)
401 func TestMSetFailure(t *testing.T) {
402 _, r, db := setupHaEnv(true)
403 expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
404 r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
405 err := db.MSet("key1", "value1", "key2", 2)
406 assert.NotNil(t, err)
407 r.AssertExpectations(t)
410 func TestMSetMPubSuccessfully(t *testing.T) {
411 _, r, db := setupHaEnv(true)
412 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
413 "chan1", "event1", "chan2", "event2"}
414 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
415 assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
416 "key1", "val1", "key2", "val2"))
417 r.AssertExpectations(t)
420 func TestMsetMPubFailure(t *testing.T) {
421 _, r, db := setupHaEnv(true)
422 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
423 "chan1", "event1", "chan2", "event2"}
424 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
425 assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
426 "key1", "val1", "key2", "val2"))
427 r.AssertExpectations(t)
430 func TestMSetMPubCommandMissing(t *testing.T) {
431 _, r, db := setupHaEnv(false)
432 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
433 "chan1", "event1", "chan2", "event2"}
434 r.AssertNotCalled(t, "Do", expectedMessage)
435 assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
436 "key1", "val1", "key2", "val2"))
437 r.AssertExpectations(t)
441 func TestMGetSuccessfully(t *testing.T) {
442 _, r, db := setupHaEnv(true)
443 expectedKeys := []string{"key1", "key2", "key3"}
444 expectedResult := []interface{}{"val1", 2, nil}
445 r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
446 result, err := db.MGet([]string{"key1", "key2", "key3"})
447 assert.Equal(t, result, expectedResult)
449 r.AssertExpectations(t)
452 func TestMGetFailure(t *testing.T) {
453 _, r, db := setupHaEnv(true)
454 expectedKeys := []string{"key1", "key2", "key3"}
455 expectedResult := []interface{}{nil}
456 r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
457 errors.New("Some error")))
458 result, err := db.MGet([]string{"key1", "key2", "key3"})
459 assert.Equal(t, result, expectedResult)
460 assert.NotNil(t, err)
461 r.AssertExpectations(t)
464 func TestDelMPubSuccessfully(t *testing.T) {
465 _, r, db := setupHaEnv(true)
466 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
468 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
469 assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
470 []string{"key1", "key2"}))
471 r.AssertExpectations(t)
474 func TestDelMPubFailure(t *testing.T) {
475 _, r, db := setupHaEnv(true)
476 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
478 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
479 assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
480 []string{"key1", "key2"}))
481 r.AssertExpectations(t)
484 func TestDelMPubCommandMissing(t *testing.T) {
485 _, r, db := setupHaEnv(false)
486 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
488 r.AssertNotCalled(t, "Do", expectedMessage)
489 assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
490 []string{"key1", "key2"}))
491 r.AssertExpectations(t)
494 func TestDelSuccessfully(t *testing.T) {
495 _, r, db := setupHaEnv(true)
496 expectedKeys := []string{"key1", "key2"}
497 r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
498 assert.Nil(t, db.Del([]string{"key1", "key2"}))
499 r.AssertExpectations(t)
502 func TestDelFailure(t *testing.T) {
503 _, r, db := setupHaEnv(true)
504 expectedKeys := []string{"key1", "key2"}
505 r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
506 assert.NotNil(t, db.Del([]string{"key1", "key2"}))
507 r.AssertExpectations(t)
510 func TestKeysSuccessfully(t *testing.T) {
511 _, r, db := setupHaEnv(true)
512 expectedPattern := "pattern*"
513 expectedResult := []string{"pattern1", "pattern2"}
514 r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
515 result, err := db.Keys("pattern*")
516 assert.Equal(t, result, expectedResult)
518 r.AssertExpectations(t)
521 func TestKeysFailure(t *testing.T) {
522 _, r, db := setupHaEnv(true)
523 expectedPattern := "pattern*"
524 expectedResult := []string{}
525 r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
526 errors.New("Some error")))
527 _, err := db.Keys("pattern*")
528 assert.NotNil(t, err)
529 r.AssertExpectations(t)
532 func TestSetIEKeyExists(t *testing.T) {
533 _, r, db := setupHaEnv(true)
534 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
535 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
536 result, err := db.SetIE("key", "olddata", "newdata")
537 assert.True(t, result)
539 r.AssertExpectations(t)
542 func TestSetIEKeyDoesntExists(t *testing.T) {
543 _, r, db := setupHaEnv(true)
544 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
545 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
546 result, err := db.SetIE("key", "olddata", "newdata")
547 assert.False(t, result)
549 r.AssertExpectations(t)
552 func TestSetIEFailure(t *testing.T) {
553 _, r, db := setupHaEnv(true)
554 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
555 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
556 result, err := db.SetIE("key", "olddata", "newdata")
557 assert.False(t, result)
558 assert.NotNil(t, err)
559 r.AssertExpectations(t)
562 func TestSetIECommandMissing(t *testing.T) {
563 _, r, db := setupHaEnv(false)
564 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
565 r.AssertNotCalled(t, "Do", expectedMessage)
566 result, err := db.SetIE("key", "olddata", "newdata")
567 assert.False(t, result)
568 assert.NotNil(t, err)
569 r.AssertExpectations(t)
572 func TestSetIEPubKeyExists(t *testing.T) {
573 _, r, db := setupHaEnv(true)
574 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
575 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
576 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
577 assert.True(t, result)
579 r.AssertExpectations(t)
582 func TestSetIEPubKeyDoesntExists(t *testing.T) {
583 _, r, db := setupHaEnv(true)
584 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
585 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
586 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
587 assert.False(t, result)
589 r.AssertExpectations(t)
592 func TestSetIEPubFailure(t *testing.T) {
593 _, r, db := setupHaEnv(true)
594 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
595 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
596 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
597 assert.False(t, result)
598 assert.NotNil(t, err)
599 r.AssertExpectations(t)
602 func TestSetIEPubCommandMissing(t *testing.T) {
603 _, r, db := setupHaEnv(false)
604 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
605 r.AssertNotCalled(t, "Do", expectedMessage)
606 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
607 assert.False(t, result)
608 assert.NotNil(t, err)
609 r.AssertExpectations(t)
612 func TestSetNXPubKeyDoesntExist(t *testing.T) {
613 _, r, db := setupHaEnv(true)
614 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
615 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
616 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
617 assert.True(t, result)
619 r.AssertExpectations(t)
622 func TestSetNXPubKeyExists(t *testing.T) {
623 _, r, db := setupHaEnv(true)
624 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
625 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
626 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
627 assert.False(t, result)
629 r.AssertExpectations(t)
632 func TestSetNXPubFailure(t *testing.T) {
633 _, r, db := setupHaEnv(true)
634 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
635 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
636 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
637 assert.False(t, result)
638 assert.NotNil(t, err)
639 r.AssertExpectations(t)
642 func TestSetNXPubCommandMissing(t *testing.T) {
643 _, r, db := setupHaEnv(false)
644 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
645 r.AssertNotCalled(t, "Do", expectedMessage)
646 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
647 assert.False(t, result)
648 assert.NotNil(t, err)
649 r.AssertExpectations(t)
652 func TestSetNXSuccessfully(t *testing.T) {
653 _, r, db := setupHaEnv(true)
655 expectedData := "data"
656 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
657 result, err := db.SetNX("key", "data", 0)
658 assert.True(t, result)
660 r.AssertExpectations(t)
663 func TestSetNXUnsuccessfully(t *testing.T) {
664 _, r, db := setupHaEnv(true)
666 expectedData := "data"
667 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
668 result, err := db.SetNX("key", "data", 0)
669 assert.False(t, result)
671 r.AssertExpectations(t)
674 func TestSetNXFailure(t *testing.T) {
675 _, r, db := setupHaEnv(true)
677 expectedData := "data"
678 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
679 Return(redis.NewBoolResult(false, errors.New("Some error")))
680 result, err := db.SetNX("key", "data", 0)
681 assert.False(t, result)
682 assert.NotNil(t, err)
683 r.AssertExpectations(t)
686 func TestDelIEPubKeyDoesntExist(t *testing.T) {
687 _, r, db := setupHaEnv(true)
688 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
689 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
690 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
691 assert.False(t, result)
693 r.AssertExpectations(t)
696 func TestDelIEPubKeyExists(t *testing.T) {
697 _, r, db := setupHaEnv(true)
698 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
699 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
700 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
701 assert.True(t, result)
703 r.AssertExpectations(t)
706 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
707 _, r, db := setupHaEnv(true)
708 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
709 r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
710 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
711 assert.True(t, result)
713 r.AssertExpectations(t)
716 func TestDelIEPubFailure(t *testing.T) {
717 _, r, db := setupHaEnv(true)
718 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
719 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
720 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
721 assert.False(t, result)
722 assert.NotNil(t, err)
723 r.AssertExpectations(t)
726 func TestDelIEPubCommandMissing(t *testing.T) {
727 _, r, db := setupHaEnv(false)
728 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
729 r.AssertNotCalled(t, "Do", expectedMessage)
730 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
731 assert.False(t, result)
732 assert.NotNil(t, err)
733 r.AssertExpectations(t)
736 func TestDelIEKeyDoesntExist(t *testing.T) {
737 _, r, db := setupHaEnv(true)
738 expectedMessage := []interface{}{"DELIE", "key", "data"}
739 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
740 result, err := db.DelIE("key", "data")
741 assert.False(t, result)
743 r.AssertExpectations(t)
746 func TestDelIEKeyExists(t *testing.T) {
747 _, r, db := setupHaEnv(true)
748 expectedMessage := []interface{}{"DELIE", "key", "data"}
749 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
750 result, err := db.DelIE("key", "data")
751 assert.True(t, result)
753 r.AssertExpectations(t)
756 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
757 _, r, db := setupHaEnv(true)
758 expectedMessage := []interface{}{"DELIE", "key", "data"}
759 r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
760 result, err := db.DelIE("key", "data")
761 assert.True(t, result)
763 r.AssertExpectations(t)
766 func TestDelIEFailure(t *testing.T) {
767 _, r, db := setupHaEnv(true)
768 expectedMessage := []interface{}{"DELIE", "key", "data"}
769 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
770 result, err := db.DelIE("key", "data")
771 assert.False(t, result)
772 assert.NotNil(t, err)
773 r.AssertExpectations(t)
776 func TestDelIECommandMissing(t *testing.T) {
777 _, r, db := setupHaEnv(false)
778 expectedMessage := []interface{}{"DELIE", "key", "data"}
779 r.AssertNotCalled(t, "Do", expectedMessage)
780 result, err := db.DelIE("key", "data")
781 assert.False(t, result)
782 assert.NotNil(t, err)
783 r.AssertExpectations(t)
786 func TestSAddSuccessfully(t *testing.T) {
787 _, r, db := setupHaEnv(true)
789 expectedData := []interface{}{"data", 2}
790 r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
791 assert.Nil(t, db.SAdd("key", "data", 2))
792 r.AssertExpectations(t)
795 func TestSAddFailure(t *testing.T) {
796 _, r, db := setupHaEnv(true)
798 expectedData := []interface{}{"data", 2}
799 r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
800 assert.NotNil(t, db.SAdd("key", "data", 2))
801 r.AssertExpectations(t)
804 func TestSRemSuccessfully(t *testing.T) {
805 _, r, db := setupHaEnv(true)
807 expectedData := []interface{}{"data", 2}
808 r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
809 assert.Nil(t, db.SRem("key", "data", 2))
810 r.AssertExpectations(t)
813 func TestSRemFailure(t *testing.T) {
814 _, r, db := setupHaEnv(true)
816 expectedData := []interface{}{"data", 2}
817 r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
818 assert.NotNil(t, db.SRem("key", "data", 2))
819 r.AssertExpectations(t)
822 func TestSMembersSuccessfully(t *testing.T) {
823 _, r, db := setupHaEnv(true)
825 expectedResult := []string{"member1", "member2"}
826 r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
827 result, err := db.SMembers("key")
828 assert.Equal(t, result, expectedResult)
830 r.AssertExpectations(t)
833 func TestSMembersFailure(t *testing.T) {
834 _, r, db := setupHaEnv(true)
836 expectedResult := []string{"member1", "member2"}
837 r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
838 errors.New("Some error")))
839 result, err := db.SMembers("key")
840 assert.Equal(t, result, expectedResult)
841 assert.NotNil(t, err)
842 r.AssertExpectations(t)
845 func TestSIsMemberIsMember(t *testing.T) {
846 _, r, db := setupHaEnv(true)
848 expectedData := "data"
849 r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
850 result, err := db.SIsMember("key", "data")
851 assert.True(t, result)
853 r.AssertExpectations(t)
856 func TestSIsMemberIsNotMember(t *testing.T) {
857 _, r, db := setupHaEnv(true)
859 expectedData := "data"
860 r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
861 result, err := db.SIsMember("key", "data")
862 assert.False(t, result)
864 r.AssertExpectations(t)
867 func TestSIsMemberFailure(t *testing.T) {
868 _, r, db := setupHaEnv(true)
870 expectedData := "data"
871 r.On("SIsMember", expectedKey, expectedData).
872 Return(redis.NewBoolResult(false, errors.New("Some error")))
873 result, err := db.SIsMember("key", "data")
874 assert.False(t, result)
875 assert.NotNil(t, err)
876 r.AssertExpectations(t)
879 func TestSCardSuccessfully(t *testing.T) {
880 _, r, db := setupHaEnv(true)
882 r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
883 result, err := db.SCard("key")
884 assert.Equal(t, int64(1), result)
886 r.AssertExpectations(t)
889 func TestSCardFailure(t *testing.T) {
890 _, r, db := setupHaEnv(true)
892 r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
893 result, err := db.SCard("key")
894 assert.Equal(t, int64(1), result)
895 assert.NotNil(t, err)
896 r.AssertExpectations(t)
899 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
900 ps, r, db := setupHaEnv(true)
901 ch := make(chan *redis.Message)
902 msg := redis.Message{
903 Channel: "{prefix},channel",
907 ps.On("Channel").Return(ch)
908 ps.On("Unsubscribe").Return(nil)
909 ps.On("Close").Return(nil)
911 receivedChannel := ""
912 db.SubscribeChannelDB(func(channel string, payload ...string) {
914 receivedChannel = channel
915 }, "{prefix},channel")
917 db.UnsubscribeChannelDB("{prefix},channel")
918 time.Sleep(1 * time.Second)
919 assert.Equal(t, 1, count)
920 assert.Equal(t, "channel", receivedChannel)
921 r.AssertExpectations(t)
922 ps.AssertExpectations(t)
925 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
926 ps, r, db := setupHaEnv(true)
927 ch := make(chan *redis.Message)
928 msg1 := redis.Message{
929 Channel: "{prefix},channel1",
933 msg2 := redis.Message{
934 Channel: "{prefix},channel2",
938 ps.On("Channel").Return(ch)
939 ps.On("Subscribe").Return(nil)
940 ps.On("Unsubscribe").Return(nil)
941 ps.On("Unsubscribe").Return(nil)
942 ps.On("Close").Return(nil)
944 receivedChannel1 := ""
945 db.SubscribeChannelDB(func(channel string, payload ...string) {
947 receivedChannel1 = channel
948 }, "{prefix},channel1")
950 receivedChannel2 := ""
951 db.SubscribeChannelDB(func(channel string, payload ...string) {
953 receivedChannel2 = channel
954 }, "{prefix},channel2")
956 time.Sleep(1 * time.Second)
957 db.UnsubscribeChannelDB("{prefix},channel1")
959 db.UnsubscribeChannelDB("{prefix},channel2")
960 time.Sleep(1 * time.Second)
961 assert.Equal(t, 2, count)
962 assert.Equal(t, "channel1", receivedChannel1)
963 assert.Equal(t, "channel2", receivedChannel2)
964 r.AssertExpectations(t)
965 ps.AssertExpectations(t)
968 func TestSubscribeChannelDBTwoSubscribesWithUnequalPrefixAndUnsubscribes(t *testing.T) {
969 ps, r, db := setupHaEnv(true)
970 ch := make(chan *redis.Message)
971 msg1 := redis.Message{
972 Channel: "{prefix1},channel",
976 msg2 := redis.Message{
977 Channel: "{prefix2},channel",
981 ps.On("Channel").Return(ch)
982 ps.On("Subscribe").Return(nil)
983 ps.On("Unsubscribe").Return(nil)
984 ps.On("Unsubscribe").Return(nil)
985 ps.On("Close").Return(nil)
987 receivedChannel1 := ""
988 db.SubscribeChannelDB(func(channel string, payload ...string) {
990 receivedChannel1 = channel
991 }, "{prefix1},channel")
993 receivedChannel2 := ""
994 db.SubscribeChannelDB(func(channel string, payload ...string) {
996 receivedChannel2 = channel
997 }, "{prefix2},channel")
999 time.Sleep(1 * time.Second)
1000 db.UnsubscribeChannelDB("{prefix1},channel")
1002 db.UnsubscribeChannelDB("{prefix2},channel")
1003 time.Sleep(1 * time.Second)
1004 assert.Equal(t, 2, count)
1005 assert.Equal(t, "channel", receivedChannel1)
1006 assert.Equal(t, "channel", receivedChannel2)
1007 r.AssertExpectations(t)
1008 ps.AssertExpectations(t)
1011 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
1012 ps, r, db := setupHaEnv(true)
1013 ch := make(chan *redis.Message)
1014 msg := redis.Message{
1015 Channel: "{prefix},channel",
1019 ps.On("Channel").Return(ch)
1020 ps.On("Unsubscribe").Return(nil)
1021 ps.On("Close").Return(nil)
1023 receivedChannel := ""
1025 db.SubscribeChannelDB(func(channel string, payload ...string) {
1027 receivedChannel = channel
1028 }, "{prefix},channel")
1030 db.UnsubscribeChannelDB("{prefix},channel")
1031 time.Sleep(1 * time.Second)
1033 db.SubscribeChannelDB(func(channel string, payload ...string) {
1035 receivedChannel = channel
1036 }, "{prefix}", "---", "{prefix},channel")
1038 db.UnsubscribeChannelDB("{prefix},channel")
1040 time.Sleep(1 * time.Second)
1041 assert.Equal(t, 2, count)
1042 assert.Equal(t, "channel", receivedChannel)
1043 r.AssertExpectations(t)
1044 ps.AssertExpectations(t)
1047 func TestSubscribeChannelDBSubscribeReceivedEventIgnoredIfChannelNameIsUnknown(t *testing.T) {
1048 ps, r, db := setupHaEnv(true)
1049 ch := make(chan *redis.Message)
1050 msg := redis.Message{
1051 Channel: "missingNsPrefixchannel",
1055 ps.On("Channel").Return(ch)
1056 ps.On("Unsubscribe").Return(nil)
1057 ps.On("Close").Return(nil)
1059 receivedChannel := ""
1060 db.SubscribeChannelDB(func(channel string, payload ...string) {
1062 receivedChannel = channel
1063 }, "{prefix},channel")
1065 db.UnsubscribeChannelDB("{prefix},channel")
1066 time.Sleep(1 * time.Second)
1067 assert.Equal(t, 0, count)
1068 assert.Equal(t, "", receivedChannel)
1069 r.AssertExpectations(t)
1070 ps.AssertExpectations(t)
1073 func TestPTTLSuccessfully(t *testing.T) {
1074 _, r, db := setupHaEnv(true)
1075 expectedKey := "key"
1076 expectedResult := time.Duration(1)
1077 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1079 result, err := db.PTTL("key")
1080 assert.Equal(t, result, expectedResult)
1082 r.AssertExpectations(t)
1085 func TestPTTLFailure(t *testing.T) {
1086 _, r, db := setupHaEnv(true)
1087 expectedKey := "key"
1088 expectedResult := time.Duration(1)
1089 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1090 errors.New("Some error")))
1091 result, err := db.PTTL("key")
1092 assert.Equal(t, result, expectedResult)
1093 assert.NotNil(t, err)
1094 r.AssertExpectations(t)
1097 func TestPExpireIESuccessfully(t *testing.T) {
1098 _, r, db := setupHaEnv(true)
1099 expectedKey := "key"
1100 expectedData := "data"
1101 expectedDuration := strconv.FormatInt(int64(10000), 10)
1103 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1104 Return(redis.NewCmdResult(int64(1), nil))
1106 err := db.PExpireIE("key", "data", 10*time.Second)
1108 r.AssertExpectations(t)
1111 func TestPExpireIEFailure(t *testing.T) {
1112 _, r, db := setupHaEnv(true)
1113 expectedKey := "key"
1114 expectedData := "data"
1115 expectedDuration := strconv.FormatInt(int64(10000), 10)
1117 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1118 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
1120 err := db.PExpireIE("key", "data", 10*time.Second)
1121 assert.NotNil(t, err)
1122 r.AssertExpectations(t)
1125 func TestPExpireIELockNotHeld(t *testing.T) {
1126 _, r, db := setupHaEnv(true)
1127 expectedKey := "key"
1128 expectedData := "data"
1129 expectedDuration := strconv.FormatInt(int64(10000), 10)
1131 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1132 Return(redis.NewCmdResult(int64(0), nil))
1134 err := db.PExpireIE("key", "data", 10*time.Second)
1135 assert.NotNil(t, err)
1136 r.AssertExpectations(t)
1139 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
1140 setupVals := setupEnv(
1142 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
1144 assert.Equal(t, 1, len(setupVals.rClient))
1145 assert.Equal(t, 1, len(setupVals.db))
1147 expectedKeysAndValues := []interface{}{"key1", "value1"}
1148 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1149 err := setupVals.db[0].MSet("key1", "value1")
1151 setupVals.rClient[0].AssertExpectations(t)
1154 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
1155 setupVals := setupEnv(
1157 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
1159 assert.Equal(t, 1, len(setupVals.rClient))
1160 assert.Equal(t, 1, len(setupVals.db))
1162 expectedKeysAndValues := []interface{}{"key1", "value1"}
1163 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1164 err := setupVals.db[0].MSet("key1", "value1")
1166 setupVals.rClient[0].AssertExpectations(t)
1169 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
1170 setupVals := setupEnv(
1172 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
1173 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
1175 assert.Equal(t, 2, len(setupVals.rClient))
1176 assert.Equal(t, 2, len(setupVals.db))
1178 expectedKeysAndValues := []interface{}{"key1", "value1"}
1179 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1180 err := setupVals.db[0].MSet("key1", "value1")
1182 setupVals.rClient[0].AssertExpectations(t)
1184 expectedKeysAndValues = []interface{}{"key2", "value2"}
1185 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1186 err = setupVals.db[1].MSet("key2", "value2")
1188 setupVals.rClient[0].AssertExpectations(t)
1189 setupVals.rClient[1].AssertExpectations(t)
1192 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1193 setupVals := setupEnv(
1195 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
1196 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1198 assert.Equal(t, 2, len(setupVals.rClient))
1199 assert.Equal(t, 2, len(setupVals.db))
1201 expectedKeysAndValues := []interface{}{"key1", "value1"}
1202 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1203 err := setupVals.db[0].MSet("key1", "value1")
1205 setupVals.rClient[0].AssertExpectations(t)
1207 expectedKeysAndValues = []interface{}{"key2", "value2"}
1208 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1209 err = setupVals.db[1].MSet("key2", "value2")
1211 setupVals.rClient[0].AssertExpectations(t)
1212 setupVals.rClient[1].AssertExpectations(t)
1215 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
1216 _, r, db := setupHaEnv(true)
1217 redisInfo := "# Replication\r\n" +
1219 "connected_slaves:2\r\n" +
1220 "min_slaves_good_slaves:2\r\n" +
1221 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1222 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1223 expInfo := &sdlgoredis.DbInfo{
1224 Fields: sdlgoredis.DbInfoFields{
1226 ConnectedReplicaCnt: 2,
1230 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1231 info, err := db.Info()
1233 assert.Equal(t, expInfo, info)
1234 r.AssertExpectations(t)
1237 func TestInfoOfPrimaryRedisWithOneReplicaOnlineAndOtherReplicaNotOnlineSuccessfully(t *testing.T) {
1238 _, r, db := setupHaEnv(true)
1239 redisInfo := "# Replication\r\n" +
1241 "connected_slaves:1\r\n" +
1242 "min_slaves_good_slaves:2\r\n" +
1243 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1244 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1245 expInfo := &sdlgoredis.DbInfo{
1246 Fields: sdlgoredis.DbInfoFields{
1248 ConnectedReplicaCnt: 1,
1252 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1253 info, err := db.Info()
1255 assert.Equal(t, expInfo, info)
1256 r.AssertExpectations(t)
1259 func TestInfoOfStandalonePrimaryRedisSuccessfully(t *testing.T) {
1260 _, r, db := setupHaEnv(true)
1261 redisInfo := "# Replication\r\n" +
1263 "connected_slaves:0\r\n" +
1264 "min_slaves_good_slaves:0\r\n"
1265 expInfo := &sdlgoredis.DbInfo{
1266 Fields: sdlgoredis.DbInfoFields{
1268 ConnectedReplicaCnt: 0,
1272 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1273 info, err := db.Info()
1275 assert.Equal(t, expInfo, info)
1276 r.AssertExpectations(t)
1279 func TestInfoOfStandalonePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1280 _, r, db := setupHaEnv(true)
1281 redisInfo := "# Replication\r\n" +
1283 "connected_slaves:not-int\r\n" +
1284 "min_slaves_good_slaves:0\r\n"
1285 expInfo := &sdlgoredis.DbInfo{
1286 Fields: sdlgoredis.DbInfoFields{
1288 ConnectedReplicaCnt: 0,
1292 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1293 info, err := db.Info()
1295 assert.Equal(t, expInfo, info)
1296 r.AssertExpectations(t)
1299 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1300 _, r, db := setupHaEnv(true)
1301 redisInfo := "!#¤%&?+?´-\r\n"
1302 expInfo := &sdlgoredis.DbInfo{}
1304 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1305 info, err := db.Info()
1307 assert.Equal(t, expInfo, info)
1308 r.AssertExpectations(t)
1311 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1312 _, r, db := setupHaEnv(true)
1313 var redisInfo string
1314 expInfo := &sdlgoredis.DbInfo{
1315 Fields: sdlgoredis.DbInfoFields{
1320 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1321 info, err := db.Info()
1323 assert.Equal(t, expInfo, info)
1324 r.AssertExpectations(t)
1327 func TestInfoWithSomeStatisticsOfStandalonePrimaryRedis(t *testing.T) {
1328 _, r, db := setupHaEnv(true)
1329 redisInfo := "# Replication\r\n" +
1331 "connected_slaves:0\r\n" +
1332 "min_slaves_good_slaves:0\r\n" +
1334 "uptime_in_days:23\r\n" +
1336 "connected_clients:2\r\n" +
1338 "used_memory:2093808\r\n" +
1339 "used_memory_human:2.00M\r\n" +
1340 "mem_fragmentation_ratio:6.44\r\n" +
1342 "total_connections_received:278\r\n" +
1344 "used_cpu_sys:1775.254919\r\n" +
1345 "# Commandstats\r\n" +
1346 "cmdstat_role:calls=1,usec=3,usec_per_call=3.00\r\n" +
1348 "db0:keys=4,expires=0,avg_ttl=0"
1349 expInfo := &sdlgoredis.DbInfo{
1350 Fields: sdlgoredis.DbInfoFields{
1352 ConnectedReplicaCnt: 0,
1353 Server: sdlgoredis.ServerInfoFields{
1356 Clients: sdlgoredis.ClientsInfoFields{
1357 ConnectedClients: 2,
1359 Memory: sdlgoredis.MeroryInfoFields{
1360 UsedMemory: 2093808,
1361 UsedMemoryHuman: "2.00M",
1362 MemFragmentationRatio: 6.44,
1364 Stats: sdlgoredis.StatsInfoFields{
1365 TotalConnectionsReceived: 278,
1367 Cpu: sdlgoredis.CpuInfoFields{
1368 UsedCpuSys: 1775.254919,
1370 Commandstats: sdlgoredis.CommandstatsInfoFields{
1371 CmdstatRole: sdlgoredis.CommandstatsValues{
1377 Keyspace: sdlgoredis.KeyspaceInfoFields{
1378 Db: sdlgoredis.KeyspaceValues{
1385 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1386 info, err := db.Info()
1388 assert.Equal(t, expInfo, info)
1389 r.AssertExpectations(t)
1392 func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1393 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1395 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1396 redisReplicasState := newMockRedisSlavesCall()
1397 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1398 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1399 redisSentinelsState := newMockRedisSentinelsCall()
1400 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1401 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1403 expState := newExpDbState(3, nil)
1404 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1405 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1406 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1407 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1408 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1410 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1411 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1412 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1413 ret, err := db.State()
1415 assert.Equal(t, expState.s, *ret)
1416 r.AssertExpectations(t)
1419 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1420 expErr := errors.New("Some error")
1421 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1423 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1424 redisReplicasState := newMockRedisSlavesCall()
1425 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1426 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1427 redisSentinelsState := newMockRedisSentinelsCall()
1428 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1429 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1431 expState := newExpDbState(3, nil)
1432 expState.addPrimary("", "", "", "", expErr)
1433 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1434 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1435 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1436 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1438 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1439 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1440 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1441 ret, err := db.State()
1442 assert.NotNil(t, err)
1443 assert.Equal(t, expState.s, *ret)
1444 r.AssertExpectations(t)
1447 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1448 expErr := errors.New("Some error")
1449 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1451 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1452 redisReplicasState := newMockRedisSlavesCall()
1453 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1454 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1455 redisSentinelsState := newMockRedisSentinelsCall()
1456 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1457 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1459 expState := newExpDbState(3, nil)
1460 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1461 expState.addReplica("", "", "", "", "", expErr)
1462 expState.addReplica("", "", "", "", "", expErr)
1463 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1464 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1466 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1467 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1468 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1469 ret, err := db.State()
1470 assert.NotNil(t, err)
1471 assert.Equal(t, expState.s, *ret)
1472 r.AssertExpectations(t)
1475 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1476 expErr := errors.New("Some error")
1477 _, r, s, db := setupHaEnvWithSentinels(true, "2")
1479 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1480 redisReplicasState := newMockRedisSlavesCall()
1481 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1482 redisSentinelsState := newMockRedisSentinelsCall()
1483 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1485 expState := newExpDbState(2, nil)
1486 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1487 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1488 expState.addSentinel("", "", "", expErr)
1490 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1491 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1492 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1493 ret, err := db.State()
1494 assert.NotNil(t, err)
1495 assert.Equal(t, expState.s, *ret)
1496 r.AssertExpectations(t)
1499 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1500 expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1501 _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1503 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1504 redisReplicasState := newMockRedisSlavesCall()
1505 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1506 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1507 redisSentinelsState := newMockRedisSentinelsCall()
1508 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1509 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1511 expState := newExpDbState(0, expErr)
1512 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1513 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1514 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1515 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1516 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1518 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1519 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1520 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1521 ret, err := db.State()
1522 assert.Equal(t, expErr, err)
1523 assert.Equal(t, expState.s, *ret)
1524 r.AssertExpectations(t)
1527 // Test case to test ignoring of a sentinel entry with zero port. Implementation has been
1528 // done because we miss the fix for the Redis Bug #9240.
1529 func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBugRedisSuccessfully(t *testing.T) {
1530 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1532 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1533 redisReplicasState := newMockRedisSlavesCall()
1534 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1535 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1536 redisSentinelsState := newMockRedisSentinelsCall()
1537 redisSentinelsState.add("10.20.30.40", "0", "s_down,sentinel,disconnected")
1538 redisSentinelsState.add("10.20.30.50", "26379", "sentinel")
1540 expState := newExpDbState(3, nil)
1541 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1542 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1543 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1544 expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
1546 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1547 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1548 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1549 ret, err := db.State()
1551 assert.Equal(t, expState.s, *ret)
1552 r.AssertExpectations(t)
1555 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1556 _, r, db := setupSingleEnv(true, "1")
1557 redisInfo := "# Replication\r\n" +
1559 "connected_slaves:0\r\n" +
1560 "min_slaves_good_slaves:0\r\n"
1562 expState := &sdlgoredis.DbState{
1564 PrimaryDbState: sdlgoredis.PrimaryDbState{
1565 Fields: sdlgoredis.PrimaryDbStateFields{
1567 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1574 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1575 ret, err := db.State()
1577 assert.Equal(t, expState, ret)
1578 r.AssertExpectations(t)
1581 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1582 expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1583 _, r, db := setupSingleEnv(true, "no-int")
1584 redisInfo := "# Replication\r\n" +
1586 "connected_slaves:0\r\n" +
1587 "min_slaves_good_slaves:0\r\n"
1589 expState := &sdlgoredis.DbState{
1592 PrimaryDbState: sdlgoredis.PrimaryDbState{
1593 Fields: sdlgoredis.PrimaryDbStateFields{
1595 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1602 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1603 ret, err := db.State()
1604 assert.Equal(t, expErr, err)
1605 assert.Equal(t, expState, ret)
1606 r.AssertExpectations(t)
1609 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1610 expErr := errors.New("Some error")
1611 _, r, db := setupSingleEnv(true, "1")
1613 expState := &sdlgoredis.DbState{
1614 PrimaryDbState: sdlgoredis.PrimaryDbState{
1619 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1620 ret, err := db.State()
1621 assert.NotNil(t, err)
1622 assert.Equal(t, expState, ret)
1623 r.AssertExpectations(t)
1626 func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1627 _, r, db := setupSingleEnv(true, "1")
1628 redisInfo := "# Replication\r\n" +
1630 "connected_slaves:0\r\n" +
1631 "min_slaves_good_slaves:0\r\n" +
1633 "uptime_in_days:12\r\n"
1635 expStatistics := &sdlgoredis.DbStatistics{
1636 Stats: []*sdlgoredis.DbStatisticsInfo{
1638 IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1640 Info: &sdlgoredis.DbInfo{
1641 Fields: sdlgoredis.DbInfoFields{
1643 Server: sdlgoredis.ServerInfoFields{
1652 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1653 ret, err := db.Statistics()
1655 assert.Equal(t, expStatistics, ret)
1656 r.AssertExpectations(t)