Read list type of environment variables
[ric-plt/sdlgo.git] / internal / sdlgoredis / sdlgoredis_test.go
index 7ed7d70..106ba6c 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (c) 2019 AT&T Intellectual Property.
-   Copyright (c) 2018-2019 Nokia.
+   Copyright (c) 2018-2022 Nokia.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
 package sdlgoredis_test
 
 import (
+       "context"
        "errors"
        "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
-       "github.com/go-redis/redis/v7"
+       "github.com/go-redis/redis/v8"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
        "strconv"
@@ -45,15 +46,15 @@ type MockOS struct {
        mock.Mock
 }
 
-func (m *pubSubMock) Channel() <-chan *redis.Message {
+func (m *pubSubMock) Channel(opts ...redis.ChannelOption) <-chan *redis.Message {
        return m.Called().Get(0).(chan *redis.Message)
 }
 
-func (m *pubSubMock) Subscribe(channels ...string) error {
+func (m *pubSubMock) Subscribe(ctx context.Context, channels ...string) error {
        return m.Called().Error(0)
 }
 
-func (m *pubSubMock) Unsubscribe(channels ...string) error {
+func (m *pubSubMock) Unsubscribe(ctx context.Context, channels ...string) error {
        return m.Called().Error(0)
 }
 
@@ -61,7 +62,7 @@ func (m *pubSubMock) Close() error {
        return m.Called().Error(0)
 }
 
-func (m *clientMock) Command() *redis.CommandsInfoCmd {
+func (m *clientMock) Command(ctx context.Context) *redis.CommandsInfoCmd {
        return m.Called().Get(0).(*redis.CommandsInfoCmd)
 }
 
@@ -69,75 +70,75 @@ func (m *clientMock) Close() error {
        return m.Called().Error(0)
 }
 
-func (m *clientMock) Subscribe(channels ...string) *redis.PubSub {
+func (m *clientMock) Subscribe(ctx context.Context, channels ...string) *redis.PubSub {
        return m.Called(channels).Get(0).(*redis.PubSub)
 }
 
-func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
+func (m *clientMock) MSet(ctx context.Context, pairs ...interface{}) *redis.StatusCmd {
        return m.Called(pairs).Get(0).(*redis.StatusCmd)
 }
 
-func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
+func (m *clientMock) Do(ctx context.Context, args ...interface{}) *redis.Cmd {
        return m.Called(args).Get(0).(*redis.Cmd)
 }
 
-func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
+func (m *clientMock) MGet(ctx context.Context, keys ...string) *redis.SliceCmd {
        return m.Called(keys).Get(0).(*redis.SliceCmd)
 }
 
-func (m *clientMock) Del(keys ...string) *redis.IntCmd {
+func (m *clientMock) Del(ctx context.Context, keys ...string) *redis.IntCmd {
        return m.Called(keys).Get(0).(*redis.IntCmd)
 }
 
-func (m *clientMock) Keys(pattern string) *redis.StringSliceCmd {
+func (m *clientMock) Keys(ctx context.Context, pattern string) *redis.StringSliceCmd {
        return m.Called(pattern).Get(0).(*redis.StringSliceCmd)
 }
 
-func (m *clientMock) SetNX(key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
+func (m *clientMock) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
        return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
 }
 
-func (m *clientMock) SAdd(key string, members ...interface{}) *redis.IntCmd {
+func (m *clientMock) SAdd(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
        return m.Called(key, members).Get(0).(*redis.IntCmd)
 }
 
-func (m *clientMock) SRem(key string, members ...interface{}) *redis.IntCmd {
+func (m *clientMock) SRem(ctx context.Context, key string, members ...interface{}) *redis.IntCmd {
        return m.Called(key, members).Get(0).(*redis.IntCmd)
 }
 
-func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
+func (m *clientMock) SMembers(ctx context.Context, key string) *redis.StringSliceCmd {
        return m.Called(key).Get(0).(*redis.StringSliceCmd)
 }
 
-func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
+func (m *clientMock) SIsMember(ctx context.Context, key string, member interface{}) *redis.BoolCmd {
        return m.Called(key, member).Get(0).(*redis.BoolCmd)
 }
 
-func (m *clientMock) SCard(key string) *redis.IntCmd {
+func (m *clientMock) SCard(ctx context.Context, key string) *redis.IntCmd {
        return m.Called(key).Get(0).(*redis.IntCmd)
 }
 
-func (m *clientMock) PTTL(key string) *redis.DurationCmd {
+func (m *clientMock) PTTL(ctx context.Context, key string) *redis.DurationCmd {
        return m.Called(key).Get(0).(*redis.DurationCmd)
 }
 
-func (m *clientMock) Eval(script string, keys []string, args ...interface{}) *redis.Cmd {
+func (m *clientMock) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd {
        return m.Called(script, keys).Get(0).(*redis.Cmd)
 }
 
-func (m *clientMock) EvalSha(sha1 string, keys []string, args ...interface{}) *redis.Cmd {
+func (m *clientMock) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd {
        return m.Called(sha1, keys, args).Get(0).(*redis.Cmd)
 }
 
-func (m *clientMock) ScriptExists(scripts ...string) *redis.BoolSliceCmd {
+func (m *clientMock) ScriptExists(ctx context.Context, scripts ...string) *redis.BoolSliceCmd {
        return m.Called(scripts).Get(0).(*redis.BoolSliceCmd)
 }
 
-func (m *clientMock) ScriptLoad(script string) *redis.StringCmd {
+func (m *clientMock) ScriptLoad(ctx context.Context, script string) *redis.StringCmd {
        return m.Called(script).Get(0).(*redis.StringCmd)
 }
 
-func (m *clientMock) Info(section ...string) *redis.StringCmd {
+func (m *clientMock) Info(ctx context.Context, section ...string) *redis.StringCmd {
        return m.Called(section).Get(0).(*redis.StringCmd)
 }
 
@@ -145,24 +146,24 @@ type MockRedisSentinel struct {
        mock.Mock
 }
 
-func (m *MockRedisSentinel) Master(name string) *redis.StringStringMapCmd {
+func (m *MockRedisSentinel) Master(ctx context.Context, name string) *redis.StringStringMapCmd {
        a := m.Called(name)
        return a.Get(0).(*redis.StringStringMapCmd)
 }
 
-func (m *MockRedisSentinel) Slaves(name string) *redis.SliceCmd {
+func (m *MockRedisSentinel) Slaves(ctx context.Context, name string) *redis.SliceCmd {
        a := m.Called(name)
        return a.Get(0).(*redis.SliceCmd)
 }
 
-func (m *MockRedisSentinel) Sentinels(name string) *redis.SliceCmd {
+func (m *MockRedisSentinel) Sentinels(ctx context.Context, name string) *redis.SliceCmd {
        a := m.Called(name)
        return a.Get(0).(*redis.SliceCmd)
 }
 
 func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
        mock := new(pubSubMock)
-       return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
+       return mock, func(ctx context.Context, client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
                return mock
        }
 }
@@ -188,9 +189,9 @@ func setupHaEnvWithSentinels(commandsExists bool, nodeCnt string) (*pubSubMock,
        setupVals := setupEnv(
                commandsExists,
                "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-               "6376",
-               "dbaasmaster",
-               "26376",
+               "6379",
+               "dbaasmaster-cluster-0",
+               "26379",
                "",
                nodeCnt,
        )
@@ -201,7 +202,7 @@ func setupSingleEnv(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMo
        setupVals := setupEnv(
                commandsExists,
                "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-               "6376", "", "", "", nodeCnt,
+               "6379", "", "", "", nodeCnt,
        )
        return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
 }
@@ -250,10 +251,11 @@ func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nod
                        return clm
                },
                subscribeNotifications,
-               func(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
+               func(addr, sentinelPort, masterName, nodeCnt string) *sdlgoredis.Sentinel {
                        s := &sdlgoredis.Sentinel{
                                IredisSentinelClient: smock,
-                               Cfg:                  cfg,
+                               MasterName:           masterName,
+                               NodeCnt:              nodeCnt,
                        }
                        return s
                },
@@ -899,7 +901,7 @@ func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
        ps, r, db := setupHaEnv(true)
        ch := make(chan *redis.Message)
        msg := redis.Message{
-               Channel: "{prefix}channel",
+               Channel: "{prefix},channel",
                Pattern: "pattern",
                Payload: "event",
        }
@@ -911,9 +913,9 @@ func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
        db.SubscribeChannelDB(func(channel string, payload ...string) {
                count++
                receivedChannel = channel
-       }, "{prefix}", "---", "{prefix}channel")
+       }, "{prefix},channel")
        ch <- &msg
-       db.UnsubscribeChannelDB("{prefix}channel")
+       db.UnsubscribeChannelDB("{prefix},channel")
        time.Sleep(1 * time.Second)
        assert.Equal(t, 1, count)
        assert.Equal(t, "channel", receivedChannel)
@@ -925,12 +927,12 @@ func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
        ps, r, db := setupHaEnv(true)
        ch := make(chan *redis.Message)
        msg1 := redis.Message{
-               Channel: "{prefix}channel1",
+               Channel: "{prefix},channel1",
                Pattern: "pattern",
                Payload: "event",
        }
        msg2 := redis.Message{
-               Channel: "{prefix}channel2",
+               Channel: "{prefix},channel2",
                Pattern: "pattern",
                Payload: "event",
        }
@@ -944,18 +946,18 @@ func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
        db.SubscribeChannelDB(func(channel string, payload ...string) {
                count++
                receivedChannel1 = channel
-       }, "{prefix}", "---", "{prefix}channel1")
+       }, "{prefix},channel1")
        ch <- &msg1
        receivedChannel2 := ""
        db.SubscribeChannelDB(func(channel string, payload ...string) {
                count++
                receivedChannel2 = channel
-       }, "{prefix}", "---", "{prefix}channel2")
+       }, "{prefix},channel2")
 
        time.Sleep(1 * time.Second)
-       db.UnsubscribeChannelDB("{prefix}channel1")
+       db.UnsubscribeChannelDB("{prefix},channel1")
        ch <- &msg2
-       db.UnsubscribeChannelDB("{prefix}channel2")
+       db.UnsubscribeChannelDB("{prefix},channel2")
        time.Sleep(1 * time.Second)
        assert.Equal(t, 2, count)
        assert.Equal(t, "channel1", receivedChannel1)
@@ -964,11 +966,54 @@ func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
        ps.AssertExpectations(t)
 }
 
+func TestSubscribeChannelDBTwoSubscribesWithUnequalPrefixAndUnsubscribes(t *testing.T) {
+       ps, r, db := setupHaEnv(true)
+       ch := make(chan *redis.Message)
+       msg1 := redis.Message{
+               Channel: "{prefix1},channel",
+               Pattern: "pattern",
+               Payload: "event",
+       }
+       msg2 := redis.Message{
+               Channel: "{prefix2},channel",
+               Pattern: "pattern",
+               Payload: "event",
+       }
+       ps.On("Channel").Return(ch)
+       ps.On("Subscribe").Return(nil)
+       ps.On("Unsubscribe").Return(nil)
+       ps.On("Unsubscribe").Return(nil)
+       ps.On("Close").Return(nil)
+       count := 0
+       receivedChannel1 := ""
+       db.SubscribeChannelDB(func(channel string, payload ...string) {
+               count++
+               receivedChannel1 = channel
+       }, "{prefix1},channel")
+       ch <- &msg1
+       receivedChannel2 := ""
+       db.SubscribeChannelDB(func(channel string, payload ...string) {
+               count++
+               receivedChannel2 = channel
+       }, "{prefix2},channel")
+
+       time.Sleep(1 * time.Second)
+       db.UnsubscribeChannelDB("{prefix1},channel")
+       ch <- &msg2
+       db.UnsubscribeChannelDB("{prefix2},channel")
+       time.Sleep(1 * time.Second)
+       assert.Equal(t, 2, count)
+       assert.Equal(t, "channel", receivedChannel1)
+       assert.Equal(t, "channel", receivedChannel2)
+       r.AssertExpectations(t)
+       ps.AssertExpectations(t)
+}
+
 func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
        ps, r, db := setupHaEnv(true)
        ch := make(chan *redis.Message)
        msg := redis.Message{
-               Channel: "{prefix}channel",
+               Channel: "{prefix},channel",
                Pattern: "pattern",
                Payload: "event",
        }
@@ -981,17 +1026,17 @@ func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
        db.SubscribeChannelDB(func(channel string, payload ...string) {
                count++
                receivedChannel = channel
-       }, "{prefix}", "---", "{prefix}channel")
+       }, "{prefix},channel")
        ch <- &msg
-       db.UnsubscribeChannelDB("{prefix}channel")
+       db.UnsubscribeChannelDB("{prefix},channel")
        time.Sleep(1 * time.Second)
 
        db.SubscribeChannelDB(func(channel string, payload ...string) {
                count++
                receivedChannel = channel
-       }, "{prefix}", "---", "{prefix}channel")
+       }, "{prefix}", "---", "{prefix},channel")
        ch <- &msg
-       db.UnsubscribeChannelDB("{prefix}channel")
+       db.UnsubscribeChannelDB("{prefix},channel")
 
        time.Sleep(1 * time.Second)
        assert.Equal(t, 2, count)
@@ -1000,6 +1045,32 @@ func TestSubscribeChannelReDBSubscribeAfterUnsubscribe(t *testing.T) {
        ps.AssertExpectations(t)
 }
 
+func TestSubscribeChannelDBSubscribeReceivedEventIgnoredIfChannelNameIsUnknown(t *testing.T) {
+       ps, r, db := setupHaEnv(true)
+       ch := make(chan *redis.Message)
+       msg := redis.Message{
+               Channel: "missingNsPrefixchannel",
+               Pattern: "pattern",
+               Payload: "event",
+       }
+       ps.On("Channel").Return(ch)
+       ps.On("Unsubscribe").Return(nil)
+       ps.On("Close").Return(nil)
+       count := 0
+       receivedChannel := ""
+       db.SubscribeChannelDB(func(channel string, payload ...string) {
+               count++
+               receivedChannel = channel
+       }, "{prefix},channel")
+       ch <- &msg
+       db.UnsubscribeChannelDB("{prefix},channel")
+       time.Sleep(1 * time.Second)
+       assert.Equal(t, 0, count)
+       assert.Equal(t, "", receivedChannel)
+       r.AssertExpectations(t)
+       ps.AssertExpectations(t)
+}
+
 func TestPTTLSuccessfully(t *testing.T) {
        _, r, db := setupHaEnv(true)
        expectedKey := "key"
@@ -1069,7 +1140,7 @@ func TestPExpireIELockNotHeld(t *testing.T) {
 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "", "", "", "",
        )
        assert.Equal(t, 1, len(setupVals.rClient))
        assert.Equal(t, 1, len(setupVals.db))
@@ -1084,7 +1155,7 @@ func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0", "26379", "", "3",
        )
        assert.Equal(t, 1, len(setupVals.rClient))
        assert.Equal(t, 1, len(setupVals.db))
@@ -1099,7 +1170,7 @@ func TestClientSentinelRedisLegacyEnv(t *testing.T) {
 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "", "",
                "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
        )
        assert.Equal(t, 2, len(setupVals.rClient))
@@ -1122,8 +1193,8 @@ func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
        )
        assert.Equal(t, 2, len(setupVals.rClient))
        assert.Equal(t, 2, len(setupVals.db))
@@ -1142,6 +1213,36 @@ func TestClientTwoSentinelRedisEnvs(t *testing.T) {
        setupVals.rClient[1].AssertExpectations(t)
 }
 
+func TestCompleteConfigIfLessPortsThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
+func TestCompleteConfigIfLessSentinelPortsThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
+func TestCompleteConfigIfLessSentinelNamesThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
        _, r, db := setupHaEnv(true)
        redisInfo := "# Replication\r\n" +
@@ -1337,15 +1438,73 @@ func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.Nil(t, err)
        assert.Equal(t, expState.s, *ret)
        r.AssertExpectations(t)
 }
 
+func TestStateWithTwoSdlClustersContainingPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       r := setupVals.rClient
+       s := setupVals.rSentinel
+       db := setupVals.db
+
+       FstRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
+       FstRedisReplicasState := newMockRedisSlavesCall()
+       FstRedisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
+       FstRedisReplicasState.add("slave", "10.20.30.50", "6379", "up", "slave")
+       FstRedisSentinelsState := newMockRedisSentinelsCall()
+       FstRedisSentinelsState.add("10.20.30.40", "26379", "sentinel")
+       FstRedisSentinelsState.add("10.20.30.50", "26379", "sentinel")
+
+       SndRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.60", "6380", "master")
+       SndRedisReplicasState := newMockRedisSlavesCall()
+       SndRedisReplicasState.add("slave", "10.20.30.70", "6380", "up", "slave")
+       SndRedisReplicasState.add("slave", "10.20.30.80", "6380", "up", "slave")
+       SndRedisSentinelsState := newMockRedisSentinelsCall()
+       SndRedisSentinelsState.add("10.20.30.70", "26380", "sentinel")
+       SndRedisSentinelsState.add("10.20.30.80", "26380", "sentinel")
+
+       FstExpState := newExpDbState(3, nil)
+       FstExpState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
+       FstExpState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
+       FstExpState.addReplica("slave", "10.20.30.50", "6379", "up", "slave", nil)
+       FstExpState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
+       FstExpState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
+
+       SndExpState := newExpDbState(3, nil)
+       SndExpState.addPrimary("master", "10.20.30.60", "6380", "master", nil)
+       SndExpState.addReplica("slave", "10.20.30.70", "6380", "up", "slave", nil)
+       SndExpState.addReplica("slave", "10.20.30.80", "6380", "up", "slave", nil)
+       SndExpState.addSentinel("10.20.30.70", "26380", "sentinel", nil)
+       SndExpState.addSentinel("10.20.30.80", "26380", "sentinel", nil)
+
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(FstRedisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisSentinelsState.resp, nil))
+
+       s[0].On("Master", "dbaasmaster-cluster-1").Return(redis.NewStringStringMapResult(SndRedisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisSentinelsState.resp, nil))
+
+       ret, err := db[0].State()
+       assert.Nil(t, err)
+       assert.Equal(t, FstExpState.s, *ret)
+
+       ret, err = db[1].State()
+       assert.Nil(t, err)
+       assert.Equal(t, SndExpState.s, *ret)
+       r[0].AssertExpectations(t)
+}
+
 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
        expErr := errors.New("Some error")
        _, r, s, db := setupHaEnvWithSentinels(true, "3")
@@ -1365,9 +1524,9 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1393,9 +1552,9 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1417,9 +1576,9 @@ func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testin
        expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
        expState.addSentinel("", "", "", expErr)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1445,15 +1604,43 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *test
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.Equal(t, expErr, err)
        assert.Equal(t, expState.s, *ret)
        r.AssertExpectations(t)
 }
 
+// Test case to test ignoring of a sentinel entry with zero port. Implementation has been
+// done because we miss the fix for the Redis Bug #9240.
+func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBugRedisSuccessfully(t *testing.T) {
+       _, r, s, db := setupHaEnvWithSentinels(true, "3")
+
+       redisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
+       redisReplicasState := newMockRedisSlavesCall()
+       redisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
+       redisReplicasState.add("slave", "10.20.30.50", "30000", "up", "slave")
+       redisSentinelsState := newMockRedisSentinelsCall()
+       redisSentinelsState.add("10.20.30.40", "0", "s_down,sentinel,disconnected")
+       redisSentinelsState.add("10.20.30.50", "26379", "sentinel")
+
+       expState := newExpDbState(3, nil)
+       expState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
+       expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
+       expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
+       expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
+
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       ret, err := db.State()
+       assert.Nil(t, err)
+       assert.Equal(t, expState.s, *ret)
+       r.AssertExpectations(t)
+}
+
 func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
        _, r, db := setupSingleEnv(true, "1")
        redisInfo := "# Replication\r\n" +
@@ -1467,7 +1654,7 @@ func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
                        Fields: sdlgoredis.PrimaryDbStateFields{
                                Role:  "master",
                                Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:  "6376",
+                               Port:  "6379",
                                Flags: "master",
                        },
                },
@@ -1495,7 +1682,7 @@ func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T)
                        Fields: sdlgoredis.PrimaryDbStateFields{
                                Role:  "master",
                                Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:  "6376",
+                               Port:  "6379",
                                Flags: "master",
                        },
                },
@@ -1538,7 +1725,7 @@ func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
                Stats: []*sdlgoredis.DbStatisticsInfo{
                        {
                                IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:   "6376",
+                               Port:   "6379",
                                Info: &sdlgoredis.DbInfo{
                                        Fields: sdlgoredis.DbInfoFields{
                                                PrimaryRole: true,