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}", "---", "{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}", "---", "{prefix}channel1")
950 receivedChannel2 := ""
951 db.SubscribeChannelDB(func(channel string, payload ...string) {
953 receivedChannel2 = channel
954 }, "{prefix}", "---", "{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 TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
969 ps, r, db := setupHaEnv(true)
970 ch := make(chan *redis.Message)
971 msg := redis.Message{
972 Channel: "{prefix}channel",
976 ps.On("Channel").Return(ch)
977 ps.On("Unsubscribe").Return(nil)
978 ps.On("Close").Return(nil)
980 receivedChannel := ""
982 db.SubscribeChannelDB(func(channel string, payload ...string) {
984 receivedChannel = channel
985 }, "{prefix}", "---", "{prefix}channel")
987 db.UnsubscribeChannelDB("{prefix}channel")
988 time.Sleep(1 * time.Second)
990 db.SubscribeChannelDB(func(channel string, payload ...string) {
992 receivedChannel = channel
993 }, "{prefix}", "---", "{prefix}channel")
995 db.UnsubscribeChannelDB("{prefix}channel")
997 time.Sleep(1 * time.Second)
998 assert.Equal(t, 2, count)
999 assert.Equal(t, "channel", receivedChannel)
1000 r.AssertExpectations(t)
1001 ps.AssertExpectations(t)
1004 func TestPTTLSuccessfully(t *testing.T) {
1005 _, r, db := setupHaEnv(true)
1006 expectedKey := "key"
1007 expectedResult := time.Duration(1)
1008 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1010 result, err := db.PTTL("key")
1011 assert.Equal(t, result, expectedResult)
1013 r.AssertExpectations(t)
1016 func TestPTTLFailure(t *testing.T) {
1017 _, r, db := setupHaEnv(true)
1018 expectedKey := "key"
1019 expectedResult := time.Duration(1)
1020 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1021 errors.New("Some error")))
1022 result, err := db.PTTL("key")
1023 assert.Equal(t, result, expectedResult)
1024 assert.NotNil(t, err)
1025 r.AssertExpectations(t)
1028 func TestPExpireIESuccessfully(t *testing.T) {
1029 _, r, db := setupHaEnv(true)
1030 expectedKey := "key"
1031 expectedData := "data"
1032 expectedDuration := strconv.FormatInt(int64(10000), 10)
1034 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1035 Return(redis.NewCmdResult(int64(1), nil))
1037 err := db.PExpireIE("key", "data", 10*time.Second)
1039 r.AssertExpectations(t)
1042 func TestPExpireIEFailure(t *testing.T) {
1043 _, r, db := setupHaEnv(true)
1044 expectedKey := "key"
1045 expectedData := "data"
1046 expectedDuration := strconv.FormatInt(int64(10000), 10)
1048 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1049 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
1051 err := db.PExpireIE("key", "data", 10*time.Second)
1052 assert.NotNil(t, err)
1053 r.AssertExpectations(t)
1056 func TestPExpireIELockNotHeld(t *testing.T) {
1057 _, r, db := setupHaEnv(true)
1058 expectedKey := "key"
1059 expectedData := "data"
1060 expectedDuration := strconv.FormatInt(int64(10000), 10)
1062 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1063 Return(redis.NewCmdResult(int64(0), nil))
1065 err := db.PExpireIE("key", "data", 10*time.Second)
1066 assert.NotNil(t, err)
1067 r.AssertExpectations(t)
1070 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
1071 setupVals := setupEnv(
1073 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
1075 assert.Equal(t, 1, len(setupVals.rClient))
1076 assert.Equal(t, 1, len(setupVals.db))
1078 expectedKeysAndValues := []interface{}{"key1", "value1"}
1079 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1080 err := setupVals.db[0].MSet("key1", "value1")
1082 setupVals.rClient[0].AssertExpectations(t)
1085 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
1086 setupVals := setupEnv(
1088 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
1090 assert.Equal(t, 1, len(setupVals.rClient))
1091 assert.Equal(t, 1, len(setupVals.db))
1093 expectedKeysAndValues := []interface{}{"key1", "value1"}
1094 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1095 err := setupVals.db[0].MSet("key1", "value1")
1097 setupVals.rClient[0].AssertExpectations(t)
1100 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
1101 setupVals := setupEnv(
1103 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
1104 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
1106 assert.Equal(t, 2, len(setupVals.rClient))
1107 assert.Equal(t, 2, len(setupVals.db))
1109 expectedKeysAndValues := []interface{}{"key1", "value1"}
1110 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1111 err := setupVals.db[0].MSet("key1", "value1")
1113 setupVals.rClient[0].AssertExpectations(t)
1115 expectedKeysAndValues = []interface{}{"key2", "value2"}
1116 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1117 err = setupVals.db[1].MSet("key2", "value2")
1119 setupVals.rClient[0].AssertExpectations(t)
1120 setupVals.rClient[1].AssertExpectations(t)
1123 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1124 setupVals := setupEnv(
1126 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
1127 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1129 assert.Equal(t, 2, len(setupVals.rClient))
1130 assert.Equal(t, 2, len(setupVals.db))
1132 expectedKeysAndValues := []interface{}{"key1", "value1"}
1133 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1134 err := setupVals.db[0].MSet("key1", "value1")
1136 setupVals.rClient[0].AssertExpectations(t)
1138 expectedKeysAndValues = []interface{}{"key2", "value2"}
1139 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1140 err = setupVals.db[1].MSet("key2", "value2")
1142 setupVals.rClient[0].AssertExpectations(t)
1143 setupVals.rClient[1].AssertExpectations(t)
1146 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
1147 _, r, db := setupHaEnv(true)
1148 redisInfo := "# Replication\r\n" +
1150 "connected_slaves:2\r\n" +
1151 "min_slaves_good_slaves:2\r\n" +
1152 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1153 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1154 expInfo := &sdlgoredis.DbInfo{
1155 Fields: sdlgoredis.DbInfoFields{
1157 ConnectedReplicaCnt: 2,
1161 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1162 info, err := db.Info()
1164 assert.Equal(t, expInfo, info)
1165 r.AssertExpectations(t)
1168 func TestInfoOfPrimaryRedisWithOneReplicaOnlineAndOtherReplicaNotOnlineSuccessfully(t *testing.T) {
1169 _, r, db := setupHaEnv(true)
1170 redisInfo := "# Replication\r\n" +
1172 "connected_slaves:1\r\n" +
1173 "min_slaves_good_slaves:2\r\n" +
1174 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1175 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1176 expInfo := &sdlgoredis.DbInfo{
1177 Fields: sdlgoredis.DbInfoFields{
1179 ConnectedReplicaCnt: 1,
1183 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1184 info, err := db.Info()
1186 assert.Equal(t, expInfo, info)
1187 r.AssertExpectations(t)
1190 func TestInfoOfStandalonePrimaryRedisSuccessfully(t *testing.T) {
1191 _, r, db := setupHaEnv(true)
1192 redisInfo := "# Replication\r\n" +
1194 "connected_slaves:0\r\n" +
1195 "min_slaves_good_slaves:0\r\n"
1196 expInfo := &sdlgoredis.DbInfo{
1197 Fields: sdlgoredis.DbInfoFields{
1199 ConnectedReplicaCnt: 0,
1203 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1204 info, err := db.Info()
1206 assert.Equal(t, expInfo, info)
1207 r.AssertExpectations(t)
1210 func TestInfoOfStandalonePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1211 _, r, db := setupHaEnv(true)
1212 redisInfo := "# Replication\r\n" +
1214 "connected_slaves:not-int\r\n" +
1215 "min_slaves_good_slaves:0\r\n"
1216 expInfo := &sdlgoredis.DbInfo{
1217 Fields: sdlgoredis.DbInfoFields{
1219 ConnectedReplicaCnt: 0,
1223 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1224 info, err := db.Info()
1226 assert.Equal(t, expInfo, info)
1227 r.AssertExpectations(t)
1230 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1231 _, r, db := setupHaEnv(true)
1232 redisInfo := "!#¤%&?+?´-\r\n"
1233 expInfo := &sdlgoredis.DbInfo{}
1235 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1236 info, err := db.Info()
1238 assert.Equal(t, expInfo, info)
1239 r.AssertExpectations(t)
1242 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1243 _, r, db := setupHaEnv(true)
1244 var redisInfo string
1245 expInfo := &sdlgoredis.DbInfo{
1246 Fields: sdlgoredis.DbInfoFields{
1251 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1252 info, err := db.Info()
1254 assert.Equal(t, expInfo, info)
1255 r.AssertExpectations(t)
1258 func TestInfoWithSomeStatisticsOfStandalonePrimaryRedis(t *testing.T) {
1259 _, r, db := setupHaEnv(true)
1260 redisInfo := "# Replication\r\n" +
1262 "connected_slaves:0\r\n" +
1263 "min_slaves_good_slaves:0\r\n" +
1265 "uptime_in_days:23\r\n" +
1267 "connected_clients:2\r\n" +
1269 "used_memory:2093808\r\n" +
1270 "used_memory_human:2.00M\r\n" +
1271 "mem_fragmentation_ratio:6.44\r\n" +
1273 "total_connections_received:278\r\n" +
1275 "used_cpu_sys:1775.254919\r\n" +
1276 "# Commandstats\r\n" +
1277 "cmdstat_role:calls=1,usec=3,usec_per_call=3.00\r\n" +
1279 "db0:keys=4,expires=0,avg_ttl=0"
1280 expInfo := &sdlgoredis.DbInfo{
1281 Fields: sdlgoredis.DbInfoFields{
1283 ConnectedReplicaCnt: 0,
1284 Server: sdlgoredis.ServerInfoFields{
1287 Clients: sdlgoredis.ClientsInfoFields{
1288 ConnectedClients: 2,
1290 Memory: sdlgoredis.MeroryInfoFields{
1291 UsedMemory: 2093808,
1292 UsedMemoryHuman: "2.00M",
1293 MemFragmentationRatio: 6.44,
1295 Stats: sdlgoredis.StatsInfoFields{
1296 TotalConnectionsReceived: 278,
1298 Cpu: sdlgoredis.CpuInfoFields{
1299 UsedCpuSys: 1775.254919,
1301 Commandstats: sdlgoredis.CommandstatsInfoFields{
1302 CmdstatRole: sdlgoredis.CommandstatsValues{
1308 Keyspace: sdlgoredis.KeyspaceInfoFields{
1309 Db: sdlgoredis.KeyspaceValues{
1316 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1317 info, err := db.Info()
1319 assert.Equal(t, expInfo, info)
1320 r.AssertExpectations(t)
1323 func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1324 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1326 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1327 redisReplicasState := newMockRedisSlavesCall()
1328 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1329 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1330 redisSentinelsState := newMockRedisSentinelsCall()
1331 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1332 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1334 expState := newExpDbState(3, nil)
1335 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1336 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1337 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1338 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1339 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1341 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1342 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1343 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1344 ret, err := db.State()
1346 assert.Equal(t, expState.s, *ret)
1347 r.AssertExpectations(t)
1350 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1351 expErr := errors.New("Some error")
1352 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1354 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1355 redisReplicasState := newMockRedisSlavesCall()
1356 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1357 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1358 redisSentinelsState := newMockRedisSentinelsCall()
1359 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1360 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1362 expState := newExpDbState(3, nil)
1363 expState.addPrimary("", "", "", "", expErr)
1364 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1365 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1366 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1367 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1369 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1370 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1371 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1372 ret, err := db.State()
1373 assert.NotNil(t, err)
1374 assert.Equal(t, expState.s, *ret)
1375 r.AssertExpectations(t)
1378 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1379 expErr := errors.New("Some error")
1380 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1382 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1383 redisReplicasState := newMockRedisSlavesCall()
1384 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1385 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1386 redisSentinelsState := newMockRedisSentinelsCall()
1387 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1388 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1390 expState := newExpDbState(3, nil)
1391 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1392 expState.addReplica("", "", "", "", "", expErr)
1393 expState.addReplica("", "", "", "", "", expErr)
1394 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1395 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1397 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1398 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1399 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1400 ret, err := db.State()
1401 assert.NotNil(t, err)
1402 assert.Equal(t, expState.s, *ret)
1403 r.AssertExpectations(t)
1406 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1407 expErr := errors.New("Some error")
1408 _, r, s, db := setupHaEnvWithSentinels(true, "2")
1410 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1411 redisReplicasState := newMockRedisSlavesCall()
1412 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1413 redisSentinelsState := newMockRedisSentinelsCall()
1414 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1416 expState := newExpDbState(2, nil)
1417 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1418 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1419 expState.addSentinel("", "", "", expErr)
1421 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1422 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1423 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1424 ret, err := db.State()
1425 assert.NotNil(t, err)
1426 assert.Equal(t, expState.s, *ret)
1427 r.AssertExpectations(t)
1430 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1431 expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1432 _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1434 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1435 redisReplicasState := newMockRedisSlavesCall()
1436 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1437 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1438 redisSentinelsState := newMockRedisSentinelsCall()
1439 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1440 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1442 expState := newExpDbState(0, expErr)
1443 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1444 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1445 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1446 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1447 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1449 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1450 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1451 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1452 ret, err := db.State()
1453 assert.Equal(t, expErr, err)
1454 assert.Equal(t, expState.s, *ret)
1455 r.AssertExpectations(t)
1458 // Test case to test ignoring of a sentinel entry with zero port. Implementation has been
1459 // done because we miss the fix for the Redis Bug #9240.
1460 func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBugRedisSuccessfully(t *testing.T) {
1461 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1463 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1464 redisReplicasState := newMockRedisSlavesCall()
1465 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1466 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1467 redisSentinelsState := newMockRedisSentinelsCall()
1468 redisSentinelsState.add("10.20.30.40", "0", "s_down,sentinel,disconnected")
1469 redisSentinelsState.add("10.20.30.50", "26379", "sentinel")
1471 expState := newExpDbState(3, nil)
1472 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1473 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1474 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1475 expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
1477 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1478 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1479 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1480 ret, err := db.State()
1482 assert.Equal(t, expState.s, *ret)
1483 r.AssertExpectations(t)
1486 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1487 _, r, db := setupSingleEnv(true, "1")
1488 redisInfo := "# Replication\r\n" +
1490 "connected_slaves:0\r\n" +
1491 "min_slaves_good_slaves:0\r\n"
1493 expState := &sdlgoredis.DbState{
1495 PrimaryDbState: sdlgoredis.PrimaryDbState{
1496 Fields: sdlgoredis.PrimaryDbStateFields{
1498 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1505 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1506 ret, err := db.State()
1508 assert.Equal(t, expState, ret)
1509 r.AssertExpectations(t)
1512 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1513 expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1514 _, r, db := setupSingleEnv(true, "no-int")
1515 redisInfo := "# Replication\r\n" +
1517 "connected_slaves:0\r\n" +
1518 "min_slaves_good_slaves:0\r\n"
1520 expState := &sdlgoredis.DbState{
1523 PrimaryDbState: sdlgoredis.PrimaryDbState{
1524 Fields: sdlgoredis.PrimaryDbStateFields{
1526 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1533 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1534 ret, err := db.State()
1535 assert.Equal(t, expErr, err)
1536 assert.Equal(t, expState, ret)
1537 r.AssertExpectations(t)
1540 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1541 expErr := errors.New("Some error")
1542 _, r, db := setupSingleEnv(true, "1")
1544 expState := &sdlgoredis.DbState{
1545 PrimaryDbState: sdlgoredis.PrimaryDbState{
1550 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1551 ret, err := db.State()
1552 assert.NotNil(t, err)
1553 assert.Equal(t, expState, ret)
1554 r.AssertExpectations(t)
1557 func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1558 _, r, db := setupSingleEnv(true, "1")
1559 redisInfo := "# Replication\r\n" +
1561 "connected_slaves:0\r\n" +
1562 "min_slaves_good_slaves:0\r\n" +
1564 "uptime_in_days:12\r\n"
1566 expStatistics := &sdlgoredis.DbStatistics{
1567 Stats: []*sdlgoredis.DbStatisticsInfo{
1569 IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1571 Info: &sdlgoredis.DbInfo{
1572 Fields: sdlgoredis.DbInfoFields{
1574 Server: sdlgoredis.ServerInfoFields{
1583 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1584 ret, err := db.Statistics()
1586 assert.Equal(t, expStatistics, ret)
1587 r.AssertExpectations(t)