--- /dev/null
+
+/*
+ Copyright (c) 2019 AT&T Intellectual Property.
+ Copyright (c) 2018-2019 Nokia.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package sdlgoredis_test
+
+import (
+ "testing"
+ "errors"
+ "time"
+
+ "github.com/go-redis/redis"
+ "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+)
+
+type clientMock struct {
+ mock.Mock
+}
+
+type pubSubMock struct {
+ mock.Mock
+}
+
+func (m *pubSubMock) Channel() <-chan *redis.Message {
+ return m.Called().Get(0).(chan *redis.Message)
+}
+
+func (m *pubSubMock) Subscribe(channels ...string) error {
+ return m.Called().Error(0)
+}
+
+func (m *pubSubMock) Unsubscribe(channels ...string) error {
+ return m.Called().Error(0)
+}
+
+func (m *pubSubMock) Close() error {
+ return m.Called().Error(0)
+}
+
+func (m *clientMock) Command() *redis.CommandsInfoCmd {
+ return m.Called().Get(0).(*redis.CommandsInfoCmd)
+}
+
+func (m *clientMock) Close() error {
+ return m.Called().Error(0)
+}
+
+func (m *clientMock) Subscribe(channels ...string) *redis.PubSub {
+ return m.Called(channels).Get(0).(*redis.PubSub)
+}
+
+func (m *clientMock) MSet(pairs ...interface{}) *redis.StatusCmd {
+ return m.Called(pairs).Get(0).(*redis.StatusCmd)
+}
+
+func (m *clientMock) Do(args ...interface{}) *redis.Cmd {
+ return m.Called(args).Get(0).(*redis.Cmd)
+}
+
+func (m *clientMock) MGet(keys ...string) *redis.SliceCmd {
+ return m.Called(keys).Get(0).(*redis.SliceCmd)
+}
+
+func (m *clientMock) Del(keys ...string) *redis.IntCmd {
+ return m.Called(keys).Get(0).(*redis.IntCmd)
+}
+
+func (m *clientMock) Keys(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 {
+ return m.Called(key, value, expiration).Get(0).(*redis.BoolCmd)
+}
+
+func (m *clientMock) SAdd(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 {
+ return m.Called(key, members).Get(0).(*redis.IntCmd)
+}
+
+func (m *clientMock) SMembers(key string) *redis.StringSliceCmd {
+ return m.Called(key).Get(0).(*redis.StringSliceCmd)
+}
+
+func (m *clientMock) SIsMember(key string, member interface{}) *redis.BoolCmd {
+ return m.Called(key, member).Get(0).(*redis.BoolCmd)
+}
+
+func (m *clientMock) SCard(key string) *redis.IntCmd {
+ return m.Called(key).Get(0).(*redis.IntCmd)
+}
+
+func setSubscribeNotifications() (*pubSubMock, sdlgoredis.SubscribeFn) {
+ mock := new(pubSubMock)
+ return mock, func(client sdlgoredis.RedisClient, channels ...string) sdlgoredis.Subscriber {
+ return mock
+ }
+}
+
+func setup(commandsExists bool) (*pubSubMock, *clientMock, *sdlgoredis.DB) {
+ mock := new(clientMock)
+ pubSubMock, subscribeNotifications := setSubscribeNotifications()
+ db := sdlgoredis.CreateDB(mock, subscribeNotifications)
+
+ dummyCommandInfo := redis.CommandInfo{
+ Name: "dummy",
+ }
+ cmdResult := make(map[string]*redis.CommandInfo, 0)
+
+ if commandsExists {
+ cmdResult = map[string]*redis.CommandInfo{
+ "setie": &dummyCommandInfo,
+ "delie": &dummyCommandInfo,
+ "setiepub": &dummyCommandInfo,
+ "setnxpub": &dummyCommandInfo,
+ "msetmpub": &dummyCommandInfo,
+ "delmpub": &dummyCommandInfo,
+ }
+ } else {
+ cmdResult = map[string]*redis.CommandInfo{
+ "dummy": &dummyCommandInfo,
+ }
+ }
+
+ mock.On("Command").Return(redis.NewCommandsInfoCmdResult(cmdResult, nil))
+ db.CheckCommands()
+ return pubSubMock, mock, db
+}
+
+func TestMSetSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
+ r.On("MSet",expectedKeysAndValues).Return(redis.NewStatusResult("OK", nil))
+ err := db.MSet("key1", "value1", "key2", 2)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestMSetFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeysAndValues := []interface{}{"key1", "value1", "key2", 2}
+ r.On("MSet",expectedKeysAndValues).Return(redis.NewStatusResult("OK", errors.New("Some error")))
+ err := db.MSet("key1", "value1", "key2", 2)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestMSetMPubSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
+ "chan1", "event1", "chan2", "event2"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
+ assert.Nil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
+ "key1", "val1", "key2", "val2"))
+ r.AssertExpectations(t)
+}
+
+func TestMsetMPubFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
+ "chan1", "event1", "chan2", "event2"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
+ assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
+ "key1", "val1", "key2", "val2"))
+ r.AssertExpectations(t)
+}
+
+func TestMSetMPubCommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"MSETMPUB", 2, 2, "key1", "val1", "key2", "val2",
+ "chan1", "event1", "chan2", "event2"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ assert.NotNil(t, db.MSetMPub([]string{"chan1", "event1", "chan2", "event2"},
+ "key1", "val1", "key2", "val2"))
+ r.AssertExpectations(t)
+
+}
+
+func TestMGetSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeys := []string{"key1", "key2", "key3"}
+ expectedResult := []interface{}{"val1", 2, nil}
+ r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult, nil))
+ result, err := db.MGet([]string{"key1", "key2", "key3"})
+ assert.Equal(t, result, expectedResult)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestMGetFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeys := []string{"key1", "key2", "key3"}
+ expectedResult := []interface{}{nil}
+ r.On("MGet", expectedKeys).Return(redis.NewSliceResult(expectedResult,
+ errors.New("Some error")))
+ result, err := db.MGet([]string{"key1", "key2", "key3"})
+ assert.Equal(t, result, expectedResult)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelMPubSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
+ "chan2", "event2"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("", nil))
+ assert.Nil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
+ []string{"key1", "key2"}))
+ r.AssertExpectations(t)
+}
+
+func TestDelMPubFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
+ "chan2", "event2"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("", errors.New("Some error")))
+ assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
+ []string{"key1", "key2"}))
+ r.AssertExpectations(t)
+}
+
+func TestDelMPubCommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"DELMPUB", 2, 2, "key1", "key2", "chan1", "event1",
+ "chan2", "event2"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ assert.NotNil(t, db.DelMPub([]string{"chan1", "event1", "chan2", "event2"},
+ []string{"key1", "key2"}))
+ r.AssertExpectations(t)
+}
+
+func TestDelSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeys := []string{"key1", "key2"}
+ r.On("Del", expectedKeys).Return(redis.NewIntResult(2, nil))
+ assert.Nil(t, db.Del([]string{"key1", "key2"}))
+ r.AssertExpectations(t)
+}
+
+func TestDelFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKeys := []string{"key1", "key2"}
+ r.On("Del", expectedKeys).Return(redis.NewIntResult(2, errors.New("Some error")))
+ assert.NotNil(t, db.Del([]string{"key1", "key2"}))
+ r.AssertExpectations(t)
+}
+
+func TestKeysSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedPattern := "pattern*"
+ expectedResult := []string{"pattern1", "pattern2"}
+ r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult, nil))
+ result, err := db.Keys("pattern*")
+ assert.Equal(t, result, expectedResult)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestKeysFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedPattern := "pattern*"
+ expectedResult := []string{}
+ r.On("Keys", expectedPattern).Return(redis.NewStringSliceResult(expectedResult,
+ errors.New("Some error")))
+ _, err := db.Keys("pattern*")
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEKeyExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
+ result, err := db.SetIE("key", "olddata", "newdata")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEKeyDoesntExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
+ result, err := db.SetIE("key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
+ result, err := db.SetIE("key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIECommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"SETIE", "key", "newdata", "olddata"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ result, err := db.SetIE("key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEPubKeyExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
+ result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEPubKeyDoesntExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
+ result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEPubFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
+ result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetIEPubCommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"SETIEPUB", "key", "newdata", "olddata", "channel", "message"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ result, err := db.SetIEPub("channel", "message", "key", "olddata", "newdata")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXPubKeyDoesntExist(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult("OK", nil))
+ result, err := db.SetNXPub("channel", "message", "key", "data")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXPubKeyExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, nil))
+ result, err := db.SetNXPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXPubFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(nil, errors.New("Some error")))
+ result, err := db.SetNXPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXPubCommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"SETNXPUB", "key", "data", "channel", "message"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ result, err := db.SetNXPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(true, nil))
+ result, err := db.SetNX("key", "data")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXUnsuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(redis.NewBoolResult(false, nil))
+ result, err := db.SetNX("key", "data")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSetNXFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SetNX", expectedKey, expectedData, time.Duration(0)).
+ Return(redis.NewBoolResult(false,errors.New("Some error")))
+ result, err := db.SetNX("key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEPubKeyDoesntExist(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, nil))
+ result, err := db.DelIEPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEPubKeyExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
+ result, err := db.DelIEPub("channel", "message", "key", "data")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEPubFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, errors.New("Some error")))
+ result, err := db.DelIEPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEPubCommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"DELIEPUB", "key", "data", "channel", "message"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ result, err := db.DelIEPub("channel", "message", "key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEKeyDoesntExist(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIE", "key", "data"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, nil))
+ result, err := db.DelIE("key", "data")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEKeyExists(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIE", "key", "data"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(1, nil))
+ result, err := db.DelIE("key", "data")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIEFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedMessage := []interface{}{"DELIE", "key", "data"}
+ r.On("Do", expectedMessage).Return(redis.NewCmdResult(0, errors.New("Some error")))
+ result, err := db.DelIE("key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestDelIECommandMissing(t *testing.T) {
+ _, r, db := setup(false)
+ expectedMessage := []interface{}{"DELIE", "key", "data"}
+ r.AssertNotCalled(t, "Do", expectedMessage)
+ result, err := db.DelIE("key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSAddSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := []interface{}{"data", 2}
+ r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
+ assert.Nil(t, db.SAdd("key", "data", 2))
+ r.AssertExpectations(t)
+}
+
+func TestSAddFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := []interface{}{"data", 2}
+ r.On("SAdd", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
+ assert.NotNil(t, db.SAdd("key", "data", 2))
+ r.AssertExpectations(t)
+}
+
+func TestSRemSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := []interface{}{"data", 2}
+ r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, nil))
+ assert.Nil(t, db.SRem("key", "data", 2))
+ r.AssertExpectations(t)
+}
+
+func TestSRemFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := []interface{}{"data", 2}
+ r.On("SRem", expectedKey, expectedData).Return(redis.NewIntResult(2, errors.New("Some error")))
+ assert.NotNil(t, db.SRem("key", "data", 2))
+ r.AssertExpectations(t)
+}
+
+func TestSMembersSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedResult := []string{"member1", "member2"}
+ r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult, nil))
+ result, err := db.SMembers("key")
+ assert.Equal(t, result, expectedResult)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSMembersFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedResult := []string{"member1", "member2"}
+ r.On("SMembers", expectedKey).Return(redis.NewStringSliceResult(expectedResult,
+ errors.New("Some error")))
+ result, err := db.SMembers("key")
+ assert.Equal(t, result, expectedResult)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSIsMemberIsMember(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(true, nil))
+ result, err := db.SIsMember("key", "data")
+ assert.True(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSIsMemberIsNotMember(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SIsMember", expectedKey, expectedData).Return(redis.NewBoolResult(false, nil))
+ result, err := db.SIsMember("key", "data")
+ assert.False(t, result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSIsMemberFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ expectedData := "data"
+ r.On("SIsMember", expectedKey, expectedData).
+ Return(redis.NewBoolResult(false, errors.New("Some error")))
+ result, err := db.SIsMember("key", "data")
+ assert.False(t, result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSCardSuccessfully(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ r.On("SCard", expectedKey).Return(redis.NewIntResult(1, nil))
+ result, err := db.SCard("key")
+ assert.Equal(t, int64(1), result)
+ assert.Nil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSCardFailure(t *testing.T) {
+ _, r, db := setup(true)
+ expectedKey := "key"
+ r.On("SCard", expectedKey).Return(redis.NewIntResult(1, errors.New("Some error")))
+ result, err := db.SCard("key")
+ assert.Equal(t, int64(1), result)
+ assert.NotNil(t, err)
+ r.AssertExpectations(t)
+}
+
+func TestSubscribeChannelDBSubscribeRXUnsubscribe(t *testing.T) {
+ ps, r, db := setup(true)
+ ch := make(chan *redis.Message)
+ msg := redis.Message{
+ Channel: "{prefix}channel",
+ 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}", "---", "{prefix}channel")
+ ch <- &msg
+ db.UnsubscribeChannelDB("{prefix}channel")
+ time.Sleep(1 * time.Second)
+ assert.Equal(t, 1, count)
+ assert.Equal(t, "channel", receivedChannel)
+ r.AssertExpectations(t)
+ ps.AssertExpectations(t)
+}
+
+func TestSubscribeChannelDBSubscribeTwoUnsubscribeOne(t *testing.T) {
+ ps, r, db := setup(true)
+ ch := make(chan *redis.Message)
+ msg1 := redis.Message{
+ Channel: "{prefix}channel1",
+ Pattern: "pattern",
+ Payload: "event",
+ }
+ msg2 := redis.Message{
+ Channel: "{prefix}channel2",
+ 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
+ },"{prefix}", "---", "{prefix}channel1")
+ ch <- &msg1
+ receivedChannel2 := ""
+ db.SubscribeChannelDB(func(channel string, payload ...string){
+ count++
+ receivedChannel2 = channel
+ },"{prefix}", "---", "{prefix}channel2")
+
+ db.UnsubscribeChannelDB("{prefix}channel1")
+ ch <- &msg2
+ db.UnsubscribeChannelDB("{prefix}channel2")
+ time.Sleep(1 * time.Second)
+ assert.Equal(t, 2, count)
+ assert.Equal(t, "channel1", receivedChannel1)
+ assert.Equal(t, "channel2", receivedChannel2)
+ r.AssertExpectations(t)
+ ps.AssertExpectations(t)
+}
\ No newline at end of file
import (
"errors"
"testing"
+ "reflect"
"gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
"gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
return a.Error(0)
}
-func (m *mockDB) MSetPub(ns, message string, pairs ...interface{}) error {
- a := m.Called(ns, message, pairs)
+func (m *mockDB) MSetMPub(channelsAndEvents []string, pairs ...interface{}) error {
+ a := m.Called(channelsAndEvents, pairs)
return a.Error(0)
}
return a.Error(0)
}
-func (m *mockDB) DelPub(channel, message string, keys []string) error {
- a := m.Called(channel, message, keys)
+func (m *mockDB) DelMPub(channelsAndEvents []string, keys []string) error {
+ a := m.Called(channelsAndEvents, keys)
return a.Error(0)
}
return m, i
}
+func verifySliceInOrder(a, b []string) bool {
+ for i, v := range a {
+ found := false
+ if i%2 == 0 {
+ for j, x := range b {
+ if j%2 == 0 && x == v && a[i+1] == b[j+1] {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false
+ }
+ }
+ }
+ return true
+
+}
+
func TestSubscribeChannel(t *testing.T) {
m, i := setup()
m.AssertExpectations(t)
}
+func TestWriteMapAsInput(t *testing.T){
+ m, i := setup()
+
+ setExpected := []interface{}{"{namespace},key1", "string123",
+ "{namespace},key22", 12,
+ "{namespace},key333", []byte{1,2,3,4,5}}
+ inputMap := map[string]interface{}{
+ "key1": "string123",
+ "key22": 12,
+ "key333": []byte{1,2,3,4,5},
+ }
+
+ m.On("MSet", mock.MatchedBy(func(input []interface{}) bool {
+ for _, v := range input {
+ found := false
+ for _, x := range setExpected {
+ found = reflect.DeepEqual(x, v)
+ if found == true {
+ break
+ }
+ }
+ if found == false {
+ return false
+ }
+ }
+ return true
+ })).Return(nil)
+
+ err := i.Set(inputMap)
+ assert.Nil(t, err)
+ m.AssertExpectations(t)
+}
+
func TestWriteMixed(t *testing.T) {
m, i := setup()
func TestWriteAndPublishOneKeyOneChannel(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedMessage := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
expectedKeyVal := []interface{}{"{namespace},key1", "data1"}
- m.On("MSetPub", expectedChannel, expectedMessage, expectedKeyVal).Return(nil)
+ m.On("MSetMPub", expectedChannelAndEvent, expectedKeyVal).Return(nil)
m.AssertNotCalled(t, "MSet", expectedKeyVal)
err := i.SetAndPublish([]string{"channel", "event"}, "key1", "data1")
assert.Nil(t, err)
m.AssertExpectations(t)
}
+
+func TestWriteAndPublishSeveralChannelsAndEvents(t *testing.T) {
+ m , i := setup()
+
+ expectedChannelsAndEvents := []string{"{namespace},channel1", "event1___event2",
+ "{namespace},channel2", "event3___event4"}
+ expectedKeyVal := []interface{}{"{namespace},key", "data"}
+
+ verifyChannelAndEvent := func(input []string) bool {
+ return verifySliceInOrder(input, expectedChannelsAndEvents)
+ }
+ m.On("MSetMPub", mock.MatchedBy(verifyChannelAndEvent), expectedKeyVal).Return(nil)
+ m.AssertNotCalled(t, "MSet", expectedKeyVal)
+ err := i.SetAndPublish([]string{"channel1", "event1", "channel2", "event3", "channel1", "event2", "channel2", "event4"},
+ "key", "data")
+ assert.Nil(t, err)
+ m.AssertExpectations(t)
+}
+
func TestWriteAndPublishOneKeyOneChannelTwoEvents(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedMessage := "event1___event2"
+ expectedChannelAndEvents := []string{"{namespace},channel", "event1___event2"}
expectedKeyVal := []interface{}{"{namespace},key1", "data1"}
- m.On("MSetPub", expectedChannel, expectedMessage, expectedKeyVal).Return(nil)
+ m.On("MSetMPub", expectedChannelAndEvents, expectedKeyVal).Return(nil)
m.AssertNotCalled(t, "MSet", expectedKeyVal)
err := i.SetAndPublish([]string{"channel", "event1", "channel", "event2"}, "key1", "data1")
assert.Nil(t, err)
func TestWriteAndPublishIncorrectChannelAndEvent(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedMessage := "event1___event2"
+ expectedChannelAndEvent := []string{}
expectedKeyVal := []interface{}{"{namespace},key1", "data1"}
- m.AssertNotCalled(t, "MSetPub", expectedChannel, expectedMessage, expectedKeyVal)
+ m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal)
m.AssertNotCalled(t, "MSet", expectedKeyVal)
err := i.SetAndPublish([]string{"channel", "event1", "channel"}, "key1", "data1")
assert.NotNil(t, err)
func TestWriteAndPublishNotAllowedCharactersInEvents(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedMessage := "event1___event2"
+ expectedChannelAndEvent := []string{}
expectedKeyVal := []interface{}{"{namespace},key1", "data1"}
- m.AssertNotCalled(t, "MSetPub", expectedChannel, expectedMessage, expectedKeyVal)
+ m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal)
m.AssertNotCalled(t, "MSet", expectedKeyVal)
err := i.SetAndPublish([]string{"channel", "event1___event2"}, "key1", "data1")
assert.NotNil(t, err)
func TestWriteAndPublishNoData(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedMessage := "event"
+ expectedChannelAndEvent := []string{}
expectedKeyVal := []interface{}{"key"}
- m.AssertNotCalled(t, "MSetPub", expectedChannel, expectedMessage, expectedKeyVal)
+ m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal)
m.AssertNotCalled(t, "MSet", expectedKeyVal)
err := i.SetAndPublish([]string{"channel", "event"}, []interface{}{"key"})
assert.NotNil(t, err)
expectedKeyVal := []interface{}{"{namespace},key1", "data1"}
m.On("MSet", expectedKeyVal).Return(nil)
- m.AssertNotCalled(t, "MSetPub", "", "", expectedKeyVal)
+ m.AssertNotCalled(t, "MSetMPub", "", "", expectedKeyVal)
err := i.SetAndPublish([]string{}, "key1", "data1")
assert.Nil(t, err)
m.AssertExpectations(t)
func TestRemoveAndPublishSuccessfully(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
expectedKeys := []string{"{namespace},key1", "{namespace},key2"}
- m.On("DelPub", expectedChannel, expectedEvent, expectedKeys).Return(nil)
+ m.On("DelMPub", expectedChannelAndEvent, expectedKeys).Return(nil)
err := i.RemoveAndPublish([]string{"channel", "event"}, []string{"key1", "key2"})
assert.Nil(t, err)
m.AssertExpectations(t)
}
+
+func TestRemoveAndPublishSeveralChannelsAndEventsSuccessfully(t *testing.T) {
+ m, i := setup()
+
+ expectedChannelAndEvent := []string{"{namespace},channel1", "event1___event2",
+ "{namespace},channel2", "event3___event4"}
+ expectedKeys := []string{"{namespace},key1", "{namespace},key2"}
+
+ verifyChannelAndEvent := func(input []string) bool {
+ return verifySliceInOrder(input, expectedChannelAndEvent)
+ }
+ m.On("DelMPub", mock.MatchedBy(verifyChannelAndEvent), expectedKeys).Return(nil)
+ err := i.RemoveAndPublish([]string{"channel1", "event1", "channel2", "event3",
+ "channel1", "event2", "channel2", "event4"},
+ []string{"key1", "key2"})
+ assert.Nil(t, err)
+ m.AssertExpectations(t)
+}
func TestRemoveAndPublishFail(t *testing.T) {
m, i := setup()
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
expectedKeys := []string{"{namespace},key1", "{namespace},key2"}
- m.On("DelPub", expectedChannel, expectedEvent, expectedKeys).Return(errors.New("Some error"))
+ m.On("DelMPub", expectedChannelAndEvent, expectedKeys).Return(errors.New("Some error"))
err := i.RemoveAndPublish([]string{"channel", "event"}, []string{"key1", "key2"})
assert.NotNil(t, err)
m.AssertExpectations(t)
func TestRemoveAndPublishIncorrectChannel(t *testing.T) {
m, i := setup()
- notExpectedChannel := "{namespace},channel"
- notExpectedEvent := "event"
+ notExpectedChannelAndEvent := []string{}
notExpectedKeys := []string{"{namespace},key"}
- m.AssertNotCalled(t, "DelPub", notExpectedChannel, notExpectedEvent, notExpectedKeys)
+ m.AssertNotCalled(t, "DelMPub", notExpectedChannelAndEvent, notExpectedKeys)
m.AssertNotCalled(t, "Del", notExpectedKeys)
err := i.RemoveAndPublish([]string{"channel", "event", "channel2"}, []string{})
assert.Nil(t, err)
func TestRemoveAndPublishNoKeys(t *testing.T) {
m, i := setup()
- notExpectedChannel := "{namespace},channel"
- notExpectedEvent := "event"
+ notExpectedChannelAndEvent := []string{}
notExpectedKeys := []string{"{namespace},key"}
- m.AssertNotCalled(t, "DelPub", notExpectedChannel, notExpectedEvent, notExpectedKeys)
+ m.AssertNotCalled(t, "DelMPub", notExpectedChannelAndEvent, notExpectedKeys)
m.AssertNotCalled(t, "Del", notExpectedKeys)
err := i.RemoveAndPublish([]string{"channel", "event"}, []string{})
assert.Nil(t, err)
mKeysExpected := string("{namespace},*")
mKeysReturn := []string{"{namespace},key1", "{namespace},key2"}
mDelExpected := mKeysReturn
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
m.On("Keys", mKeysExpected).Return(mKeysReturn, nil)
- m.On("DelPub", expectedChannel, expectedEvent, mDelExpected).Return(nil)
+ m.On("DelMPub", expectedChannelAndEvent, mDelExpected).Return(nil)
err := i.RemoveAllAndPublish([]string{"channel", "event"})
assert.Nil(t, err)
m.AssertExpectations(t)
mKeysExpected := string("{namespace},*")
mKeysReturn := []string{"{namespace},key1", "{namespace},key2"}
mDelExpected := mKeysReturn
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event" }
m.On("Keys", mKeysExpected).Return(mKeysReturn, errors.New("Some error"))
- m.AssertNotCalled(t, "DelPub", expectedChannel, expectedEvent, mDelExpected)
+ m.AssertNotCalled(t, "DelMPub", expectedChannelAndEvent, mDelExpected)
err := i.RemoveAllAndPublish([]string{"channel", "event"})
assert.NotNil(t, err)
m.AssertExpectations(t)
mKeysExpected := string("{namespace},*")
mKeysReturn := []string{"{namespace},key1", "{namespace},key2"}
mDelExpected := mKeysReturn
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
m.On("Keys", mKeysExpected).Return(mKeysReturn, nil)
- m.On("DelPub", expectedChannel, expectedEvent, mDelExpected).Return(errors.New("Some error"))
+ m.On("DelMPub", expectedChannelAndEvent, mDelExpected).Return(errors.New("Some error"))
err := i.RemoveAllAndPublish([]string{"channel", "event"})
assert.NotNil(t, err)
m.AssertExpectations(t)
mKeysExpected := string("{namespace},*")
mKeysReturn := []string{"{namespace},key1", "{namespace},key2"}
mDelExpected := mKeysReturn
- expectedChannel := "{namespace},channel"
- expectedEvent := "event"
+ expectedChannelAndEvent := []string{"{namespace},channel", "event"}
m.On("Keys", mKeysExpected).Return(mKeysReturn, nil)
- m.AssertNotCalled(t, "DelPub", expectedChannel, expectedEvent, mDelExpected)
+ m.AssertNotCalled(t, "DelMPub", expectedChannelAndEvent, mDelExpected)
err := i.RemoveAllAndPublish([]string{"channel", "event___anotherEvent"})
assert.NotNil(t, err)
m.AssertExpectations(t)
mDelExpected := mKeysReturn
m.On("Keys", mKeysExpected).Return(mKeysReturn, nil)
m.On("Del", mDelExpected).Return(nil)
- m.AssertNotCalled(t, "DelPub", "", "", mDelExpected)
+ m.AssertNotCalled(t, "DelMPub", "", "", mDelExpected)
err := i.RemoveAllAndPublish([]string{})
assert.Nil(t, err)
m.AssertExpectations(t)
mKeysReturn := []string{"{namespace},key1", "{namespace},key2"}
mDelExpected := mKeysReturn
m.On("Keys", mKeysExpected).Return(mKeysReturn, nil)
- m.AssertNotCalled(t, "DelPub", "", "", mDelExpected)
+ m.AssertNotCalled(t, "DelMPub", "", "", mDelExpected)
err := i.RemoveAllAndPublish([]string{"channel", "event", "channel2"})
assert.NotNil(t, err)
m.AssertExpectations(t)