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
27 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
28 "github.com/go-redis/redis/v7"
29 "github.com/stretchr/testify/assert"
30 "github.com/stretchr/testify/mock"
36 type clientMock struct {
40 type pubSubMock struct {
48 func (m *pubSubMock) Channel() <-chan *redis.Message {
49 return m.Called().Get(0).(chan *redis.Message)
52 func (m *pubSubMock) Subscribe(channels ...string) error {
53 return m.Called().Error(0)
56 func (m *pubSubMock) Unsubscribe(channels ...string) error {
57 return m.Called().Error(0)
60 func (m *pubSubMock) Close() error {
61 return m.Called().Error(0)
64 func (m *clientMock) Command() *redis.CommandsInfoCmd {
65 return m.Called().Get(0).(*redis.CommandsInfoCmd)
68 func (m *clientMock) Close() error {
69 return m.Called().Error(0)
72 func (m *clientMock) Subscribe(channels ...string) *redis.PubSub {
73 return m.Called(channels).Get(0).(*redis.PubSub)
76 func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
77 return m.Called(pairs).Get(0).(*redis.StatusCmd)
80 func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
81 return m.Called(args).Get(0).(*redis.Cmd)
84 func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
85 return m.Called(keys).Get(0).(*redis.SliceCmd)
88 func (m *clientMock) Del(keys ...string) *redis.IntCmd {
89 return m.Called(keys).Get(0).(*redis.IntCmd)
92 func (m *clientMock) Keys(pattern string) *redis.StringSliceCmd {
93 return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
96 func (m *clientMock) SetNX(key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
97 return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
100 func (m *clientMock) SAdd(key string, members ...interface{}) *redis.IntCmd {
101 return m.Called(key, members).Get(0).(*redis.IntCmd)
104 func (m *clientMock) SRem(key string, members ...interface{}) *redis.IntCmd {
105 return m.Called(key, members).Get(0).(*redis.IntCmd)
108 func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
109 return m.Called(key).Get(0).(*redis.StringSliceCmd)
112 func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
113 return m.Called(key, member).Get(0).(*redis.BoolCmd)
116 func (m *clientMock) SCard(key string) *redis.IntCmd {
117 return m.Called(key).Get(0).(*redis.IntCmd)
120 func (m *clientMock) PTTL(key string) *redis.DurationCmd {
121 return m.Called(key).Get(0).(*redis.DurationCmd)
124 func (m *clientMock) Eval(script string, keys []string, args ...interface{}) *redis.Cmd {
125 return m.Called(script, keys).Get(0).(*redis.Cmd)
128 func (m *clientMock) EvalSha(sha1 string, keys []string, args ...interface{}) *redis.Cmd {
129 return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
132 func (m *clientMock) ScriptExists(scripts ...string) *redis.BoolSliceCmd {
133 return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
136 func (m *clientMock) ScriptLoad(script string) *redis.StringCmd {
137 return m.Called(script).Get(0).(*redis.StringCmd)
140 func (m *clientMock) Info(section ...string) *redis.StringCmd {
141 return m.Called(section).Get(0).(*redis.StringCmd)
144 type MockRedisSentinel struct {
148 func (m *MockRedisSentinel) Master(name string) *redis.StringStringMapCmd {
150 return a.Get(0).(*redis.StringStringMapCmd)
153 func (m *MockRedisSentinel) Slaves(name string) *redis.SliceCmd {
155 return a.Get(0).(*redis.SliceCmd)
158 func (m *MockRedisSentinel) Sentinels(name string) *redis.SliceCmd {
160 return a.Get(0).(*redis.SliceCmd)
163 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
164 mock := new(pubSubMock)
165 return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
170 func (m *MockOS) Getenv(key string, defValue string) string {
171 a := m.Called(key, defValue)
175 type setupEv struct {
176 pubSubMock []*pubSubMock
177 rClient []*clientMock
178 rSentinel []*MockRedisSentinel
182 func setupHaEnv(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
183 psm, cm, _, db := setupHaEnvWithSentinels(commandsExists, "3")
187 func setupHaEnvWithSentinels(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, []*MockRedisSentinel, *sdlgoredis.DB) {
188 setupVals := setupEnv(
190 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
197 return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.rSentinel, setupVals.db[0]
200 func setupSingleEnv(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
201 setupVals := setupEnv(
203 "service-ricplt-dbaas-tcp-cluster-0.ricplt",
204 "6376", "", "", "", nodeCnt,
206 return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
209 func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nodeCnt string) setupEv {
212 dummyCommandInfo := redis.CommandInfo{
216 cmdResult := make(map[string]*redis.CommandInfo, 0)
218 cmdResult = map[string]*redis.CommandInfo{
219 "setie": &dummyCommandInfo,
220 "delie": &dummyCommandInfo,
221 "setiepub": &dummyCommandInfo,
222 "setnxpub": &dummyCommandInfo,
223 "msetmpub": &dummyCommandInfo,
224 "delmpub": &dummyCommandInfo,
227 cmdResult = map[string]*redis.CommandInfo{
228 "dummy": &dummyCommandInfo,
232 osmock := new(MockOS)
233 osmock.On("Getenv", "DBAAS_SERVICE_HOST", "localhost").Return(host)
234 osmock.On("Getenv", "DBAAS_SERVICE_PORT", "6379").Return(port)
235 osmock.On("Getenv", "DBAAS_MASTER_NAME", "").Return(msname)
236 osmock.On("Getenv", "DBAAS_SERVICE_SENTINEL_PORT", "").Return(sntport)
237 osmock.On("Getenv", "DBAAS_CLUSTER_ADDR_LIST", "").Return(clsaddrlist)
238 osmock.On("Getenv", "DBAAS_NODE_COUNT", "1").Return(nodeCnt)
240 pubSubMock, subscribeNotifications := setSubscribeNotifications()
241 smock := new(MockRedisSentinel)
242 ret.rSentinel = append(ret.rSentinel, smock)
243 clients := sdlgoredis.ReadConfigAndCreateDbClients(
245 func(addr, port, clusterName string, isHa bool) sdlgoredis.RedisClient {
246 clm := new(clientMock)
247 clm.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
248 ret.rClient = append(ret.rClient, clm)
249 ret.pubSubMock = append(ret.pubSubMock, pubSubMock)
252 subscribeNotifications,
253 func(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
254 s := &sdlgoredis.Sentinel{
255 IredisSentinelClient: smock,
265 func newMockRedisMasterCallResp(role, ip, port, flag string) map[string]string {
266 resp := map[string]string{}
268 resp["role-reported"] = role
276 type mockRedisSlaves struct {
280 func newMockRedisSlavesCall() *mockRedisSlaves {
281 return new(mockRedisSlaves)
284 func (mrr *mockRedisSlaves) add(role, ip, port, link, flag string) {
285 mrr.resp = append(mrr.resp,
287 "role-reported", role,
290 "master-link-status", link,
296 type mockRedisSentinels struct {
300 func newMockRedisSentinelsCall() *mockRedisSentinels {
301 return new(mockRedisSentinels)
304 func (mrs *mockRedisSentinels) add(ip, port, flag string) {
305 mrs.resp = append(mrs.resp,
314 type ExpDbState struct {
318 func newExpDbState(nodeCnt int, err error) *ExpDbState {
319 state := new(ExpDbState)
320 state.s.ConfigNodeCnt = nodeCnt
325 func (edbs *ExpDbState) addPrimary(role, ip, port, flag string, err error) {
326 edbs.s.PrimaryDbState.Err = err
327 edbs.s.PrimaryDbState.Fields = sdlgoredis.PrimaryDbStateFields{
335 func (edbs *ExpDbState) addReplica(role, ip, port, link, flag string, err error) {
336 if edbs.s.ReplicasDbState == nil {
337 edbs.s.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
338 edbs.s.ReplicasDbState.States = make([]*sdlgoredis.ReplicaDbState, 0)
340 edbs.s.ReplicasDbState.Err = err
341 if ip != "" || port != "" || link != "" || flag != "" {
342 edbs.s.ReplicasDbState.States = append(edbs.s.ReplicasDbState.States,
343 &sdlgoredis.ReplicaDbState{
344 Fields: sdlgoredis.ReplicaDbStateFields{
348 PrimaryLinkStatus: link,
356 func (edbs *ExpDbState) addSentinel(ip, port, flag string, err error) {
357 if edbs.s.SentinelsDbState == nil {
358 edbs.s.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
359 edbs.s.SentinelsDbState.States = make([]*sdlgoredis.SentinelDbState, 0)
361 edbs.s.SentinelsDbState.Err = err
362 if ip != "" || port != "" || flag != "" {
363 edbs.s.SentinelsDbState.States = append(edbs.s.SentinelsDbState.States,
364 &sdlgoredis.SentinelDbState{
365 Fields: sdlgoredis.SentinelDbStateFields{
375 func TestCloseDbSuccessfully(t *testing.T) {
376 _, r, db := setupHaEnv(true)
377 r.On("Close").Return(nil)
380 r.AssertExpectations(t)
383 func TestCloseDbFailure(t *testing.T) {
384 _, r, db := setupHaEnv(true)
385 r.On("Close").Return(errors.New("Some error"))
387 assert.NotNil(t, err)
388 r.AssertExpectations(t)
391 func TestMSetSuccessfully(t *testing.T) {
392 _, r, db := setupHaEnv(true)
393 expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
394 r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
395 err := db.MSet("key1", "value1", "key2", 2)
397 r.AssertExpectations(t)
400 func TestMSetFailure(t *testing.T) {
401 _, r, db := setupHaEnv(true)
402 expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
403 r.On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
404 err := db.MSet("key1", "value1", "key2", 2)
405 assert.NotNil(t, err)
406 r.AssertExpectations(t)
409 func TestMSetMPubSuccessfully(t *testing.T) {
410 _, r, db := setupHaEnv(true)
411 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
412 "chan1", "event1", "chan2", "event2"}
413 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
414 assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
415 "key1", "val1", "key2", "val2"))
416 r.AssertExpectations(t)
419 func TestMsetMPubFailure(t *testing.T) {
420 _, r, db := setupHaEnv(true)
421 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
422 "chan1", "event1", "chan2", "event2"}
423 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
424 assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
425 "key1", "val1", "key2", "val2"))
426 r.AssertExpectations(t)
429 func TestMSetMPubCommandMissing(t *testing.T) {
430 _, r, db := setupHaEnv(false)
431 expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
432 "chan1", "event1", "chan2", "event2"}
433 r.AssertNotCalled(t, "Do", expectedMessage)
434 assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
435 "key1", "val1", "key2", "val2"))
436 r.AssertExpectations(t)
440 func TestMGetSuccessfully(t *testing.T) {
441 _, r, db := setupHaEnv(true)
442 expectedKeys := []string{"key1", "key2", "key3"}
443 expectedResult := []interface{}{"val1", 2, nil}
444 r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
445 result, err := db.MGet([]string{"key1", "key2", "key3"})
446 assert.Equal(t, result, expectedResult)
448 r.AssertExpectations(t)
451 func TestMGetFailure(t *testing.T) {
452 _, r, db := setupHaEnv(true)
453 expectedKeys := []string{"key1", "key2", "key3"}
454 expectedResult := []interface{}{nil}
455 r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
456 errors.New("Some error")))
457 result, err := db.MGet([]string{"key1", "key2", "key3"})
458 assert.Equal(t, result, expectedResult)
459 assert.NotNil(t, err)
460 r.AssertExpectations(t)
463 func TestDelMPubSuccessfully(t *testing.T) {
464 _, r, db := setupHaEnv(true)
465 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
467 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
468 assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
469 []string{"key1", "key2"}))
470 r.AssertExpectations(t)
473 func TestDelMPubFailure(t *testing.T) {
474 _, r, db := setupHaEnv(true)
475 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
477 r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
478 assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
479 []string{"key1", "key2"}))
480 r.AssertExpectations(t)
483 func TestDelMPubCommandMissing(t *testing.T) {
484 _, r, db := setupHaEnv(false)
485 expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
487 r.AssertNotCalled(t, "Do", expectedMessage)
488 assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
489 []string{"key1", "key2"}))
490 r.AssertExpectations(t)
493 func TestDelSuccessfully(t *testing.T) {
494 _, r, db := setupHaEnv(true)
495 expectedKeys := []string{"key1", "key2"}
496 r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
497 assert.Nil(t, db.Del([]string{"key1", "key2"}))
498 r.AssertExpectations(t)
501 func TestDelFailure(t *testing.T) {
502 _, r, db := setupHaEnv(true)
503 expectedKeys := []string{"key1", "key2"}
504 r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
505 assert.NotNil(t, db.Del([]string{"key1", "key2"}))
506 r.AssertExpectations(t)
509 func TestKeysSuccessfully(t *testing.T) {
510 _, r, db := setupHaEnv(true)
511 expectedPattern := "pattern*"
512 expectedResult := []string{"pattern1", "pattern2"}
513 r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
514 result, err := db.Keys("pattern*")
515 assert.Equal(t, result, expectedResult)
517 r.AssertExpectations(t)
520 func TestKeysFailure(t *testing.T) {
521 _, r, db := setupHaEnv(true)
522 expectedPattern := "pattern*"
523 expectedResult := []string{}
524 r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
525 errors.New("Some error")))
526 _, err := db.Keys("pattern*")
527 assert.NotNil(t, err)
528 r.AssertExpectations(t)
531 func TestSetIEKeyExists(t *testing.T) {
532 _, r, db := setupHaEnv(true)
533 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
534 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
535 result, err := db.SetIE("key", "olddata", "newdata")
536 assert.True(t, result)
538 r.AssertExpectations(t)
541 func TestSetIEKeyDoesntExists(t *testing.T) {
542 _, r, db := setupHaEnv(true)
543 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
544 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
545 result, err := db.SetIE("key", "olddata", "newdata")
546 assert.False(t, result)
548 r.AssertExpectations(t)
551 func TestSetIEFailure(t *testing.T) {
552 _, r, db := setupHaEnv(true)
553 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
554 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
555 result, err := db.SetIE("key", "olddata", "newdata")
556 assert.False(t, result)
557 assert.NotNil(t, err)
558 r.AssertExpectations(t)
561 func TestSetIECommandMissing(t *testing.T) {
562 _, r, db := setupHaEnv(false)
563 expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
564 r.AssertNotCalled(t, "Do", expectedMessage)
565 result, err := db.SetIE("key", "olddata", "newdata")
566 assert.False(t, result)
567 assert.NotNil(t, err)
568 r.AssertExpectations(t)
571 func TestSetIEPubKeyExists(t *testing.T) {
572 _, r, db := setupHaEnv(true)
573 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
574 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
575 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
576 assert.True(t, result)
578 r.AssertExpectations(t)
581 func TestSetIEPubKeyDoesntExists(t *testing.T) {
582 _, r, db := setupHaEnv(true)
583 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
584 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
585 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
586 assert.False(t, result)
588 r.AssertExpectations(t)
591 func TestSetIEPubFailure(t *testing.T) {
592 _, r, db := setupHaEnv(true)
593 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
594 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
595 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
596 assert.False(t, result)
597 assert.NotNil(t, err)
598 r.AssertExpectations(t)
601 func TestSetIEPubCommandMissing(t *testing.T) {
602 _, r, db := setupHaEnv(false)
603 expectedMessage := []interface{}{"SETIEMPUB", "key", "newdata", "olddata", "channel", "message"}
604 r.AssertNotCalled(t, "Do", expectedMessage)
605 result, err := db.SetIEPub([]string{"channel", "message"}, "key", "olddata", "newdata")
606 assert.False(t, result)
607 assert.NotNil(t, err)
608 r.AssertExpectations(t)
611 func TestSetNXPubKeyDoesntExist(t *testing.T) {
612 _, r, db := setupHaEnv(true)
613 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
614 r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
615 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
616 assert.True(t, result)
618 r.AssertExpectations(t)
621 func TestSetNXPubKeyExists(t *testing.T) {
622 _, r, db := setupHaEnv(true)
623 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
624 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
625 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
626 assert.False(t, result)
628 r.AssertExpectations(t)
631 func TestSetNXPubFailure(t *testing.T) {
632 _, r, db := setupHaEnv(true)
633 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
634 r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
635 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
636 assert.False(t, result)
637 assert.NotNil(t, err)
638 r.AssertExpectations(t)
641 func TestSetNXPubCommandMissing(t *testing.T) {
642 _, r, db := setupHaEnv(false)
643 expectedMessage := []interface{}{"SETNXMPUB", "key", "data", "channel", "message"}
644 r.AssertNotCalled(t, "Do", expectedMessage)
645 result, err := db.SetNXPub([]string{"channel", "message"}, "key", "data")
646 assert.False(t, result)
647 assert.NotNil(t, err)
648 r.AssertExpectations(t)
651 func TestSetNXSuccessfully(t *testing.T) {
652 _, r, db := setupHaEnv(true)
654 expectedData := "data"
655 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
656 result, err := db.SetNX("key", "data", 0)
657 assert.True(t, result)
659 r.AssertExpectations(t)
662 func TestSetNXUnsuccessfully(t *testing.T) {
663 _, r, db := setupHaEnv(true)
665 expectedData := "data"
666 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
667 result, err := db.SetNX("key", "data", 0)
668 assert.False(t, result)
670 r.AssertExpectations(t)
673 func TestSetNXFailure(t *testing.T) {
674 _, r, db := setupHaEnv(true)
676 expectedData := "data"
677 r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
678 Return(redis.NewBoolResult(false, errors.New("Some error")))
679 result, err := db.SetNX("key", "data", 0)
680 assert.False(t, result)
681 assert.NotNil(t, err)
682 r.AssertExpectations(t)
685 func TestDelIEPubKeyDoesntExist(t *testing.T) {
686 _, r, db := setupHaEnv(true)
687 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
688 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
689 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
690 assert.False(t, result)
692 r.AssertExpectations(t)
695 func TestDelIEPubKeyExists(t *testing.T) {
696 _, r, db := setupHaEnv(true)
697 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
698 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
699 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
700 assert.True(t, result)
702 r.AssertExpectations(t)
705 func TestDelIEPubKeyExistsIntTypeRedisValue(t *testing.T) {
706 _, r, db := setupHaEnv(true)
707 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
708 r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
709 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
710 assert.True(t, result)
712 r.AssertExpectations(t)
715 func TestDelIEPubFailure(t *testing.T) {
716 _, r, db := setupHaEnv(true)
717 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
718 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
719 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
720 assert.False(t, result)
721 assert.NotNil(t, err)
722 r.AssertExpectations(t)
725 func TestDelIEPubCommandMissing(t *testing.T) {
726 _, r, db := setupHaEnv(false)
727 expectedMessage := []interface{}{"DELIEMPUB", "key", "data", "channel", "message"}
728 r.AssertNotCalled(t, "Do", expectedMessage)
729 result, err := db.DelIEPub([]string{"channel", "message"}, "key", "data")
730 assert.False(t, result)
731 assert.NotNil(t, err)
732 r.AssertExpectations(t)
735 func TestDelIEKeyDoesntExist(t *testing.T) {
736 _, r, db := setupHaEnv(true)
737 expectedMessage := []interface{}{"DELIE", "key", "data"}
738 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), nil))
739 result, err := db.DelIE("key", "data")
740 assert.False(t, result)
742 r.AssertExpectations(t)
745 func TestDelIEKeyExists(t *testing.T) {
746 _, r, db := setupHaEnv(true)
747 expectedMessage := []interface{}{"DELIE", "key", "data"}
748 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(1), nil))
749 result, err := db.DelIE("key", "data")
750 assert.True(t, result)
752 r.AssertExpectations(t)
755 func TestDelIEKeyExistsIntTypeRedisValue(t *testing.T) {
756 _, r, db := setupHaEnv(true)
757 expectedMessage := []interface{}{"DELIE", "key", "data"}
758 r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
759 result, err := db.DelIE("key", "data")
760 assert.True(t, result)
762 r.AssertExpectations(t)
765 func TestDelIEFailure(t *testing.T) {
766 _, r, db := setupHaEnv(true)
767 expectedMessage := []interface{}{"DELIE", "key", "data"}
768 r.On("Do", expectedMessage).Return(redis.NewCmdResult(int64(0), errors.New("Some error")))
769 result, err := db.DelIE("key", "data")
770 assert.False(t, result)
771 assert.NotNil(t, err)
772 r.AssertExpectations(t)
775 func TestDelIECommandMissing(t *testing.T) {
776 _, r, db := setupHaEnv(false)
777 expectedMessage := []interface{}{"DELIE", "key", "data"}
778 r.AssertNotCalled(t, "Do", expectedMessage)
779 result, err := db.DelIE("key", "data")
780 assert.False(t, result)
781 assert.NotNil(t, err)
782 r.AssertExpectations(t)
785 func TestSAddSuccessfully(t *testing.T) {
786 _, r, db := setupHaEnv(true)
788 expectedData := []interface{}{"data", 2}
789 r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
790 assert.Nil(t, db.SAdd("key", "data", 2))
791 r.AssertExpectations(t)
794 func TestSAddFailure(t *testing.T) {
795 _, r, db := setupHaEnv(true)
797 expectedData := []interface{}{"data", 2}
798 r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
799 assert.NotNil(t, db.SAdd("key", "data", 2))
800 r.AssertExpectations(t)
803 func TestSRemSuccessfully(t *testing.T) {
804 _, r, db := setupHaEnv(true)
806 expectedData := []interface{}{"data", 2}
807 r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
808 assert.Nil(t, db.SRem("key", "data", 2))
809 r.AssertExpectations(t)
812 func TestSRemFailure(t *testing.T) {
813 _, r, db := setupHaEnv(true)
815 expectedData := []interface{}{"data", 2}
816 r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
817 assert.NotNil(t, db.SRem("key", "data", 2))
818 r.AssertExpectations(t)
821 func TestSMembersSuccessfully(t *testing.T) {
822 _, r, db := setupHaEnv(true)
824 expectedResult := []string{"member1", "member2"}
825 r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
826 result, err := db.SMembers("key")
827 assert.Equal(t, result, expectedResult)
829 r.AssertExpectations(t)
832 func TestSMembersFailure(t *testing.T) {
833 _, r, db := setupHaEnv(true)
835 expectedResult := []string{"member1", "member2"}
836 r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
837 errors.New("Some error")))
838 result, err := db.SMembers("key")
839 assert.Equal(t, result, expectedResult)
840 assert.NotNil(t, err)
841 r.AssertExpectations(t)
844 func TestSIsMemberIsMember(t *testing.T) {
845 _, r, db := setupHaEnv(true)
847 expectedData := "data"
848 r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
849 result, err := db.SIsMember("key", "data")
850 assert.True(t, result)
852 r.AssertExpectations(t)
855 func TestSIsMemberIsNotMember(t *testing.T) {
856 _, r, db := setupHaEnv(true)
858 expectedData := "data"
859 r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
860 result, err := db.SIsMember("key", "data")
861 assert.False(t, result)
863 r.AssertExpectations(t)
866 func TestSIsMemberFailure(t *testing.T) {
867 _, r, db := setupHaEnv(true)
869 expectedData := "data"
870 r.On("SIsMember", expectedKey, expectedData).
871 Return(redis.NewBoolResult(false, errors.New("Some error")))
872 result, err := db.SIsMember("key", "data")
873 assert.False(t, result)
874 assert.NotNil(t, err)
875 r.AssertExpectations(t)
878 func TestSCardSuccessfully(t *testing.T) {
879 _, r, db := setupHaEnv(true)
881 r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
882 result, err := db.SCard("key")
883 assert.Equal(t, int64(1), result)
885 r.AssertExpectations(t)
888 func TestSCardFailure(t *testing.T) {
889 _, r, db := setupHaEnv(true)
891 r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
892 result, err := db.SCard("key")
893 assert.Equal(t, int64(1), result)
894 assert.NotNil(t, err)
895 r.AssertExpectations(t)
898 func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
899 ps, r, db := setupHaEnv(true)
900 ch := make(chan *redis.Message)
901 msg := redis.Message{
902 Channel: "{prefix}channel",
906 ps.On("Channel").Return(ch)
907 ps.On("Unsubscribe").Return(nil)
908 ps.On("Close").Return(nil)
910 receivedChannel := ""
911 db.SubscribeChannelDB(func(channel string, payload ...string) {
913 receivedChannel = channel
914 }, "{prefix}", "---", "{prefix}channel")
916 db.UnsubscribeChannelDB("{prefix}channel")
917 time.Sleep(1 * time.Second)
918 assert.Equal(t, 1, count)
919 assert.Equal(t, "channel", receivedChannel)
920 r.AssertExpectations(t)
921 ps.AssertExpectations(t)
924 func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
925 ps, r, db := setupHaEnv(true)
926 ch := make(chan *redis.Message)
927 msg1 := redis.Message{
928 Channel: "{prefix}channel1",
932 msg2 := redis.Message{
933 Channel: "{prefix}channel2",
937 ps.On("Channel").Return(ch)
938 ps.On("Subscribe").Return(nil)
939 ps.On("Unsubscribe").Return(nil)
940 ps.On("Unsubscribe").Return(nil)
941 ps.On("Close").Return(nil)
943 receivedChannel1 := ""
944 db.SubscribeChannelDB(func(channel string, payload ...string) {
946 receivedChannel1 = channel
947 }, "{prefix}", "---", "{prefix}channel1")
949 receivedChannel2 := ""
950 db.SubscribeChannelDB(func(channel string, payload ...string) {
952 receivedChannel2 = channel
953 }, "{prefix}", "---", "{prefix}channel2")
955 time.Sleep(1 * time.Second)
956 db.UnsubscribeChannelDB("{prefix}channel1")
958 db.UnsubscribeChannelDB("{prefix}channel2")
959 time.Sleep(1 * time.Second)
960 assert.Equal(t, 2, count)
961 assert.Equal(t, "channel1", receivedChannel1)
962 assert.Equal(t, "channel2", receivedChannel2)
963 r.AssertExpectations(t)
964 ps.AssertExpectations(t)
967 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
968 ps, r, db := setupHaEnv(true)
969 ch := make(chan *redis.Message)
970 msg := redis.Message{
971 Channel: "{prefix}channel",
975 ps.On("Channel").Return(ch)
976 ps.On("Unsubscribe").Return(nil)
977 ps.On("Close").Return(nil)
979 receivedChannel := ""
981 db.SubscribeChannelDB(func(channel string, payload ...string) {
983 receivedChannel = channel
984 }, "{prefix}", "---", "{prefix}channel")
986 db.UnsubscribeChannelDB("{prefix}channel")
987 time.Sleep(1 * time.Second)
989 db.SubscribeChannelDB(func(channel string, payload ...string) {
991 receivedChannel = channel
992 }, "{prefix}", "---", "{prefix}channel")
994 db.UnsubscribeChannelDB("{prefix}channel")
996 time.Sleep(1 * time.Second)
997 assert.Equal(t, 2, count)
998 assert.Equal(t, "channel", receivedChannel)
999 r.AssertExpectations(t)
1000 ps.AssertExpectations(t)
1003 func TestPTTLSuccessfully(t *testing.T) {
1004 _, r, db := setupHaEnv(true)
1005 expectedKey := "key"
1006 expectedResult := time.Duration(1)
1007 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1009 result, err := db.PTTL("key")
1010 assert.Equal(t, result, expectedResult)
1012 r.AssertExpectations(t)
1015 func TestPTTLFailure(t *testing.T) {
1016 _, r, db := setupHaEnv(true)
1017 expectedKey := "key"
1018 expectedResult := time.Duration(1)
1019 r.On("PTTL", expectedKey).Return(redis.NewDurationResult(expectedResult,
1020 errors.New("Some error")))
1021 result, err := db.PTTL("key")
1022 assert.Equal(t, result, expectedResult)
1023 assert.NotNil(t, err)
1024 r.AssertExpectations(t)
1027 func TestPExpireIESuccessfully(t *testing.T) {
1028 _, r, db := setupHaEnv(true)
1029 expectedKey := "key"
1030 expectedData := "data"
1031 expectedDuration := strconv.FormatInt(int64(10000), 10)
1033 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1034 Return(redis.NewCmdResult(int64(1), nil))
1036 err := db.PExpireIE("key", "data", 10*time.Second)
1038 r.AssertExpectations(t)
1041 func TestPExpireIEFailure(t *testing.T) {
1042 _, r, db := setupHaEnv(true)
1043 expectedKey := "key"
1044 expectedData := "data"
1045 expectedDuration := strconv.FormatInt(int64(10000), 10)
1047 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1048 Return(redis.NewCmdResult(int64(1), errors.New("Some error")))
1050 err := db.PExpireIE("key", "data", 10*time.Second)
1051 assert.NotNil(t, err)
1052 r.AssertExpectations(t)
1055 func TestPExpireIELockNotHeld(t *testing.T) {
1056 _, r, db := setupHaEnv(true)
1057 expectedKey := "key"
1058 expectedData := "data"
1059 expectedDuration := strconv.FormatInt(int64(10000), 10)
1061 r.On("EvalSha", mock.Anything, []string{expectedKey}, []interface{}{expectedData, expectedDuration}).
1062 Return(redis.NewCmdResult(int64(0), nil))
1064 err := db.PExpireIE("key", "data", 10*time.Second)
1065 assert.NotNil(t, err)
1066 r.AssertExpectations(t)
1069 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
1070 setupVals := setupEnv(
1072 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
1074 assert.Equal(t, 1, len(setupVals.rClient))
1075 assert.Equal(t, 1, len(setupVals.db))
1077 expectedKeysAndValues := []interface{}{"key1", "value1"}
1078 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1079 err := setupVals.db[0].MSet("key1", "value1")
1081 setupVals.rClient[0].AssertExpectations(t)
1084 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
1085 setupVals := setupEnv(
1087 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
1089 assert.Equal(t, 1, len(setupVals.rClient))
1090 assert.Equal(t, 1, len(setupVals.db))
1092 expectedKeysAndValues := []interface{}{"key1", "value1"}
1093 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1094 err := setupVals.db[0].MSet("key1", "value1")
1096 setupVals.rClient[0].AssertExpectations(t)
1099 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
1100 setupVals := setupEnv(
1102 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
1103 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
1105 assert.Equal(t, 2, len(setupVals.rClient))
1106 assert.Equal(t, 2, len(setupVals.db))
1108 expectedKeysAndValues := []interface{}{"key1", "value1"}
1109 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1110 err := setupVals.db[0].MSet("key1", "value1")
1112 setupVals.rClient[0].AssertExpectations(t)
1114 expectedKeysAndValues = []interface{}{"key2", "value2"}
1115 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1116 err = setupVals.db[1].MSet("key2", "value2")
1118 setupVals.rClient[0].AssertExpectations(t)
1119 setupVals.rClient[1].AssertExpectations(t)
1122 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
1123 setupVals := setupEnv(
1125 "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
1126 "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
1128 assert.Equal(t, 2, len(setupVals.rClient))
1129 assert.Equal(t, 2, len(setupVals.db))
1131 expectedKeysAndValues := []interface{}{"key1", "value1"}
1132 setupVals.rClient[0].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1133 err := setupVals.db[0].MSet("key1", "value1")
1135 setupVals.rClient[0].AssertExpectations(t)
1137 expectedKeysAndValues = []interface{}{"key2", "value2"}
1138 setupVals.rClient[1].On("MSet", expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
1139 err = setupVals.db[1].MSet("key2", "value2")
1141 setupVals.rClient[0].AssertExpectations(t)
1142 setupVals.rClient[1].AssertExpectations(t)
1145 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
1146 _, r, db := setupHaEnv(true)
1147 redisInfo := "# Replication\r\n" +
1149 "connected_slaves:2\r\n" +
1150 "min_slaves_good_slaves:2\r\n" +
1151 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1152 "slave1:ip=5.6.7.8,port=6379,state=online,offset=100200300,lag=0\r\n"
1153 expInfo := &sdlgoredis.DbInfo{
1154 Fields: sdlgoredis.DbInfoFields{
1156 ConnectedReplicaCnt: 2,
1160 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1161 info, err := db.Info()
1163 assert.Equal(t, expInfo, info)
1164 r.AssertExpectations(t)
1167 func TestInfoOfPrimaryRedisWithOneReplicaOnlineAndOtherReplicaNotOnlineSuccessfully(t *testing.T) {
1168 _, r, db := setupHaEnv(true)
1169 redisInfo := "# Replication\r\n" +
1171 "connected_slaves:1\r\n" +
1172 "min_slaves_good_slaves:2\r\n" +
1173 "slave0:ip=1.2.3.4,port=6379,state=online,offset=100200300,lag=0\r\n" +
1174 "slave1:ip=5.6.7.8,port=6379,state=wait_bgsave,offset=100200300,lag=0\r\n"
1175 expInfo := &sdlgoredis.DbInfo{
1176 Fields: sdlgoredis.DbInfoFields{
1178 ConnectedReplicaCnt: 1,
1182 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1183 info, err := db.Info()
1185 assert.Equal(t, expInfo, info)
1186 r.AssertExpectations(t)
1189 func TestInfoOfStandalonePrimaryRedisSuccessfully(t *testing.T) {
1190 _, r, db := setupHaEnv(true)
1191 redisInfo := "# Replication\r\n" +
1193 "connected_slaves:0\r\n" +
1194 "min_slaves_good_slaves:0\r\n"
1195 expInfo := &sdlgoredis.DbInfo{
1196 Fields: sdlgoredis.DbInfoFields{
1198 ConnectedReplicaCnt: 0,
1202 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1203 info, err := db.Info()
1205 assert.Equal(t, expInfo, info)
1206 r.AssertExpectations(t)
1209 func TestInfoOfStandalonePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1210 _, r, db := setupHaEnv(true)
1211 redisInfo := "# Replication\r\n" +
1213 "connected_slaves:not-int\r\n" +
1214 "min_slaves_good_slaves:0\r\n"
1215 expInfo := &sdlgoredis.DbInfo{
1216 Fields: sdlgoredis.DbInfoFields{
1218 ConnectedReplicaCnt: 0,
1222 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1223 info, err := db.Info()
1225 assert.Equal(t, expInfo, info)
1226 r.AssertExpectations(t)
1229 func TestInfoWithGibberishContentSuccessfully(t *testing.T) {
1230 _, r, db := setupHaEnv(true)
1231 redisInfo := "!#¤%&?+?´-\r\n"
1232 expInfo := &sdlgoredis.DbInfo{}
1234 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1235 info, err := db.Info()
1237 assert.Equal(t, expInfo, info)
1238 r.AssertExpectations(t)
1241 func TestInfoWithEmptyContentSuccessfully(t *testing.T) {
1242 _, r, db := setupHaEnv(true)
1243 var redisInfo string
1244 expInfo := &sdlgoredis.DbInfo{
1245 Fields: sdlgoredis.DbInfoFields{
1250 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1251 info, err := db.Info()
1253 assert.Equal(t, expInfo, info)
1254 r.AssertExpectations(t)
1257 func TestInfoWithSomeStatisticsOfStandalonePrimaryRedis(t *testing.T) {
1258 _, r, db := setupHaEnv(true)
1259 redisInfo := "# Replication\r\n" +
1261 "connected_slaves:0\r\n" +
1262 "min_slaves_good_slaves:0\r\n" +
1264 "uptime_in_days:23\r\n" +
1266 "connected_clients:2\r\n" +
1268 "used_memory:2093808\r\n" +
1269 "used_memory_human:2.00M\r\n" +
1270 "mem_fragmentation_ratio:6.44\r\n" +
1272 "total_connections_received:278\r\n" +
1274 "used_cpu_sys:1775.254919\r\n" +
1275 "# Commandstats\r\n" +
1276 "# cmdstat_role:calls=1,usec=3,usec_per_call=3.00\r\n" +
1278 "db0:keys=4,expires=0,avg_ttl=0"
1279 expInfo := &sdlgoredis.DbInfo{
1280 Fields: sdlgoredis.DbInfoFields{
1282 ConnectedReplicaCnt: 0,
1283 Server: sdlgoredis.ServerInfoFields{
1286 Clients: sdlgoredis.ClientsInfoFields{
1287 ConnectedClients: 2,
1289 Memory: sdlgoredis.MeroryInfoFields{
1290 UsedMemory: 2093808,
1291 UsedMemoryHuman: "2.00M",
1292 MemFragmentationRatio: 6.44,
1294 Stats: sdlgoredis.StatsInfoFields{
1295 TotalConnectionsReceived: 278,
1297 Cpu: sdlgoredis.CpuInfoFields{
1298 UsedCpuSys: 1775.254919,
1300 Commandstats: sdlgoredis.CommandstatsInfoFields{
1301 CmdstatRole: sdlgoredis.CommandstatsValues{
1307 Keyspace: sdlgoredis.KeyspaceInfoFields{
1308 Db: sdlgoredis.KeyspaceValues{
1315 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1316 info, err := db.Info()
1318 assert.Equal(t, expInfo, info)
1319 r.AssertExpectations(t)
1322 func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1323 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1325 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1326 redisReplicasState := newMockRedisSlavesCall()
1327 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1328 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1329 redisSentinelsState := newMockRedisSentinelsCall()
1330 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1331 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1333 expState := newExpDbState(3, nil)
1334 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1335 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1336 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1337 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1338 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1340 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1341 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1342 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1343 ret, err := db.State()
1345 assert.Equal(t, expState.s, *ret)
1346 r.AssertExpectations(t)
1349 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1350 expErr := errors.New("Some error")
1351 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1353 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1354 redisReplicasState := newMockRedisSlavesCall()
1355 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1356 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1357 redisSentinelsState := newMockRedisSentinelsCall()
1358 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1359 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1361 expState := newExpDbState(3, nil)
1362 expState.addPrimary("", "", "", "", expErr)
1363 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1364 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1365 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1366 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1368 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1369 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1370 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1371 ret, err := db.State()
1372 assert.NotNil(t, err)
1373 assert.Equal(t, expState.s, *ret)
1374 r.AssertExpectations(t)
1377 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1378 expErr := errors.New("Some error")
1379 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1381 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1382 redisReplicasState := newMockRedisSlavesCall()
1383 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1384 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1385 redisSentinelsState := newMockRedisSentinelsCall()
1386 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1387 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1389 expState := newExpDbState(3, nil)
1390 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1391 expState.addReplica("", "", "", "", "", expErr)
1392 expState.addReplica("", "", "", "", "", expErr)
1393 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1394 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1396 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1397 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1398 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1399 ret, err := db.State()
1400 assert.NotNil(t, err)
1401 assert.Equal(t, expState.s, *ret)
1402 r.AssertExpectations(t)
1405 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1406 expErr := errors.New("Some error")
1407 _, r, s, db := setupHaEnvWithSentinels(true, "2")
1409 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1410 redisReplicasState := newMockRedisSlavesCall()
1411 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1412 redisSentinelsState := newMockRedisSentinelsCall()
1413 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1415 expState := newExpDbState(2, nil)
1416 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1417 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1418 expState.addSentinel("", "", "", expErr)
1420 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1421 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1422 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1423 ret, err := db.State()
1424 assert.NotNil(t, err)
1425 assert.Equal(t, expState.s, *ret)
1426 r.AssertExpectations(t)
1429 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1430 expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1431 _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1433 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1434 redisReplicasState := newMockRedisSlavesCall()
1435 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1436 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1437 redisSentinelsState := newMockRedisSentinelsCall()
1438 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1439 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1441 expState := newExpDbState(0, expErr)
1442 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1443 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1444 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1445 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1446 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1448 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1449 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1450 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1451 ret, err := db.State()
1452 assert.Equal(t, expErr, err)
1453 assert.Equal(t, expState.s, *ret)
1454 r.AssertExpectations(t)
1457 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1458 _, r, db := setupSingleEnv(true, "1")
1459 redisInfo := "# Replication\r\n" +
1461 "connected_slaves:0\r\n" +
1462 "min_slaves_good_slaves:0\r\n"
1464 expState := &sdlgoredis.DbState{
1466 PrimaryDbState: sdlgoredis.PrimaryDbState{
1467 Fields: sdlgoredis.PrimaryDbStateFields{
1469 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1476 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1477 ret, err := db.State()
1479 assert.Equal(t, expState, ret)
1480 r.AssertExpectations(t)
1483 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1484 expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1485 _, r, db := setupSingleEnv(true, "no-int")
1486 redisInfo := "# Replication\r\n" +
1488 "connected_slaves:0\r\n" +
1489 "min_slaves_good_slaves:0\r\n"
1491 expState := &sdlgoredis.DbState{
1494 PrimaryDbState: sdlgoredis.PrimaryDbState{
1495 Fields: sdlgoredis.PrimaryDbStateFields{
1497 Ip: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1504 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1505 ret, err := db.State()
1506 assert.Equal(t, expErr, err)
1507 assert.Equal(t, expState, ret)
1508 r.AssertExpectations(t)
1511 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1512 expErr := errors.New("Some error")
1513 _, r, db := setupSingleEnv(true, "1")
1515 expState := &sdlgoredis.DbState{
1516 PrimaryDbState: sdlgoredis.PrimaryDbState{
1521 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1522 ret, err := db.State()
1523 assert.NotNil(t, err)
1524 assert.Equal(t, expState, ret)
1525 r.AssertExpectations(t)
1528 func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1529 _, r, db := setupSingleEnv(true, "1")
1530 redisInfo := "# Replication\r\n" +
1532 "connected_slaves:0\r\n" +
1533 "min_slaves_good_slaves:0\r\n" +
1535 "uptime_in_days:12\r\n"
1537 expStatistics := &sdlgoredis.DbStatistics{
1538 Stats: []*sdlgoredis.DbStatisticsInfo{
1540 IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
1542 Info: &sdlgoredis.DbInfo{
1543 Fields: sdlgoredis.DbInfoFields{
1545 Server: sdlgoredis.ServerInfoFields{
1554 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1555 ret, err := db.Statistics()
1557 assert.Equal(t, expStatistics, ret)
1558 r.AssertExpectations(t)