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 expErr := errors.New("Info reply error: strconv.ParseUint: parsing \"not-int\": invalid syntax")
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()
1225 assert.Equal(t, expErr, err)
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 TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
1259 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1261 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1262 redisReplicasState := newMockRedisSlavesCall()
1263 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1264 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1265 redisSentinelsState := newMockRedisSentinelsCall()
1266 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1267 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1269 expState := newExpDbState(3, nil)
1270 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1271 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1272 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1273 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1274 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1276 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1277 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1278 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1279 ret, err := db.State()
1281 assert.Equal(t, expState.s, *ret)
1282 r.AssertExpectations(t)
1285 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
1286 expErr := errors.New("Some error")
1287 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1289 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1290 redisReplicasState := newMockRedisSlavesCall()
1291 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1292 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1293 redisSentinelsState := newMockRedisSentinelsCall()
1294 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1295 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1297 expState := newExpDbState(3, nil)
1298 expState.addPrimary("", "", "", "", expErr)
1299 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1300 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1301 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1302 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1304 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
1305 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1306 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1307 ret, err := db.State()
1308 assert.NotNil(t, err)
1309 assert.Equal(t, expState.s, *ret)
1310 r.AssertExpectations(t)
1313 func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing.T) {
1314 expErr := errors.New("Some error")
1315 _, r, s, db := setupHaEnvWithSentinels(true, "3")
1317 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1318 redisReplicasState := newMockRedisSlavesCall()
1319 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1320 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1321 redisSentinelsState := newMockRedisSentinelsCall()
1322 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1323 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1325 expState := newExpDbState(3, nil)
1326 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1327 expState.addReplica("", "", "", "", "", expErr)
1328 expState.addReplica("", "", "", "", "", expErr)
1329 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1330 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1332 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1333 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
1334 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1335 ret, err := db.State()
1336 assert.NotNil(t, err)
1337 assert.Equal(t, expState.s, *ret)
1338 r.AssertExpectations(t)
1341 func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testing.T) {
1342 expErr := errors.New("Some error")
1343 _, r, s, db := setupHaEnvWithSentinels(true, "2")
1345 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1346 redisReplicasState := newMockRedisSlavesCall()
1347 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1348 redisSentinelsState := newMockRedisSentinelsCall()
1349 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1351 expState := newExpDbState(2, nil)
1352 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1353 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1354 expState.addSentinel("", "", "", expErr)
1356 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1357 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1358 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
1359 ret, err := db.State()
1360 assert.NotNil(t, err)
1361 assert.Equal(t, expState.s, *ret)
1362 r.AssertExpectations(t)
1365 func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *testing.T) {
1366 expErr := errors.New("Sentinel DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1367 _, r, s, db := setupHaEnvWithSentinels(true, "no-int")
1369 redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
1370 redisReplicasState := newMockRedisSlavesCall()
1371 redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
1372 redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
1373 redisSentinelsState := newMockRedisSentinelsCall()
1374 redisSentinelsState.add("10.20.30.40", "26379", "sentinel")
1375 redisSentinelsState.add("10.20.30.50", "30001", "sentinel")
1377 expState := newExpDbState(0, expErr)
1378 expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
1379 expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
1380 expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
1381 expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
1382 expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
1384 s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
1385 s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
1386 s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
1387 ret, err := db.State()
1388 assert.Equal(t, expErr, err)
1389 assert.Equal(t, expState.s, *ret)
1390 r.AssertExpectations(t)
1393 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
1394 _, r, db := setupSingleEnv(true, "1")
1395 redisInfo := "# Replication\r\n" +
1397 "connected_slaves:0\r\n" +
1398 "min_slaves_good_slaves:0\r\n"
1400 expState := &sdlgoredis.DbState{
1402 PrimaryDbState: sdlgoredis.PrimaryDbState{
1403 Fields: sdlgoredis.PrimaryDbStateFields{
1410 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1411 ret, err := db.State()
1413 assert.Equal(t, expState, ret)
1414 r.AssertExpectations(t)
1417 func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T) {
1418 expErr := errors.New("DBAAS_NODE_COUNT configuration value 'no-int' conversion to integer failed")
1419 _, r, db := setupSingleEnv(true, "no-int")
1420 redisInfo := "# Replication\r\n" +
1422 "connected_slaves:0\r\n" +
1423 "min_slaves_good_slaves:0\r\n"
1425 expState := &sdlgoredis.DbState{
1428 PrimaryDbState: sdlgoredis.PrimaryDbState{
1429 Fields: sdlgoredis.PrimaryDbStateFields{
1436 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, nil))
1437 ret, err := db.State()
1438 assert.Equal(t, expErr, err)
1439 assert.Equal(t, expState, ret)
1440 r.AssertExpectations(t)
1443 func TestStateWithSinglePrimaryRedisFailureInInfoCall(t *testing.T) {
1444 expErr := errors.New("Some error")
1445 _, r, db := setupSingleEnv(true, "1")
1447 expState := &sdlgoredis.DbState{
1448 PrimaryDbState: sdlgoredis.PrimaryDbState{
1453 r.On("Info", []string{"all"}).Return(redis.NewStringResult(redisInfo, errors.New("Some error")))
1454 ret, err := db.State()
1455 assert.NotNil(t, err)
1456 assert.Equal(t, expState, ret)
1457 r.AssertExpectations(t)