X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=sdl_test.go;h=944edaae2073712a68ec83c2facaf3b5d6abfccd;hb=51847d2ee72873fca9de000b77c593a0503fdbcc;hp=dbd073f8087e81cf1aba9e3a9a340f899f933c23;hpb=9617339c09dfd2a0dca05afadb07ae3f7f06a9c6;p=ric-plt%2Fsdlgo.git diff --git a/sdl_test.go b/sdl_test.go index dbd073f..944edaa 100644 --- a/sdl_test.go +++ b/sdl_test.go @@ -19,9 +19,11 @@ package sdlgo_test import ( "errors" + "reflect" "testing" + "time" - "gerrit.oran-osc.org/r/ric-plt/sdlgo" + "gerrit.o-ran-sc.org/r/ric-plt/sdlgo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -30,11 +32,24 @@ type mockDB struct { mock.Mock } +func (m *mockDB) SubscribeChannelDB(cb func(string, ...string), channelPrefix, eventSeparator string, channels ...string) { + m.Called(cb, channelPrefix, eventSeparator, channels) +} + +func (m *mockDB) UnsubscribeChannelDB(channels ...string) { + m.Called(channels) +} + func (m *mockDB) MSet(pairs ...interface{}) error { a := m.Called(pairs) return a.Error(0) } +func (m *mockDB) MSetMPub(channelsAndEvents []string, pairs ...interface{}) error { + a := m.Called(channelsAndEvents, pairs) + return a.Error(0) +} + func (m *mockDB) MGet(keys []string) ([]interface{}, error) { a := m.Called(keys) return a.Get(0).([]interface{}), a.Error(1) @@ -50,6 +65,11 @@ func (m *mockDB) Del(keys []string) error { return a.Error(0) } +func (m *mockDB) DelMPub(channelsAndEvents []string, keys []string) error { + a := m.Called(channelsAndEvents, keys) + return a.Error(0) +} + func (m *mockDB) Keys(pattern string) ([]string, error) { a := m.Called(pattern) return a.Get(0).([]string), a.Error(1) @@ -60,8 +80,18 @@ func (m *mockDB) SetIE(key string, oldData, newData interface{}) (bool, error) { return a.Bool(0), a.Error(1) } -func (m *mockDB) SetNX(key string, data interface{}) (bool, error) { - a := m.Called(key, data) +func (m *mockDB) SetIEPub(channel, message, key string, oldData, newData interface{}) (bool, error) { + a := m.Called(channel, message, key, oldData, newData) + return a.Bool(0), a.Error(1) +} + +func (m *mockDB) SetNX(key string, data interface{}, expiration time.Duration) (bool, error) { + a := m.Called(key, data, expiration) + return a.Bool(0), a.Error(1) +} + +func (m *mockDB) SetNXPub(channel, message, key string, data interface{}) (bool, error) { + a := m.Called(channel, message, key, data) return a.Bool(0), a.Error(1) } @@ -70,12 +100,90 @@ func (m *mockDB) DelIE(key string, data interface{}) (bool, error) { return a.Bool(0), a.Error(1) } +func (m *mockDB) DelIEPub(channel, message, key string, data interface{}) (bool, error) { + a := m.Called(channel, message, key, data) + return a.Bool(0), a.Error(1) +} + +func (m *mockDB) SAdd(key string, data ...interface{}) error { + a := m.Called(key, data) + return a.Error(0) +} + +func (m *mockDB) SRem(key string, data ...interface{}) error { + a := m.Called(key, data) + return a.Error(0) +} +func (m *mockDB) SMembers(key string) ([]string, error) { + a := m.Called(key) + return a.Get(0).([]string), a.Error(1) +} + +func (m *mockDB) SIsMember(key string, data interface{}) (bool, error) { + a := m.Called(key, data) + return a.Bool(0), a.Error(1) +} + +func (m *mockDB) SCard(key string) (int64, error) { + a := m.Called(key) + return a.Get(0).(int64), a.Error(1) +} + +func (m *mockDB) PTTL(key string) (time.Duration, error) { + a := m.Called(key) + return a.Get(0).(time.Duration), a.Error(1) +} + +func (m *mockDB) PExpireIE(key string, data interface{}, expiration time.Duration) error { + a := m.Called(key, data, expiration) + return a.Error(0) +} + func setup() (*mockDB, *sdlgo.SdlInstance) { m := new(mockDB) - i := sdlgo.NewSdlInstance("namespace", m) + i := sdlgo.NewSdlInstanceForTest("namespace", m) 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() + + expectedCB := func(channel string, events ...string) {} + expectedChannels := []string{"{namespace},channel1", "{namespace},channel2"} + + m.On("SubscribeChannelDB", mock.AnythingOfType("func(string, ...string)"), "{namespace},", "___", expectedChannels).Return() + i.SubscribeChannel(expectedCB, "channel1", "channel2") + m.AssertExpectations(t) +} + +func TestUnsubscribeChannel(t *testing.T) { + m, i := setup() + + expectedChannels := []string{"{namespace},channel1", "{namespace},channel2"} + + m.On("UnsubscribeChannelDB", expectedChannels).Return() + i.UnsubscribeChannel("channel1", "channel2") + m.AssertExpectations(t) +} func TestGetOneKey(t *testing.T) { m, i := setup() @@ -161,6 +269,103 @@ func TestWriteOneKey(t *testing.T) { m.AssertExpectations(t) } +func TestWriteByteSliceAsValue(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{"{namespace},key1", []byte{1, 2, 3, 4, 5}} + + m.On("MSet", msetExpected).Return(nil) + err := i.Set("key1", []byte{1, 2, 3, 4, 5}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestWriteByteSliceAsValueMixed(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{"{namespace},key1", []byte{1, 2, 3, 4, 5}, "{namespace},key2", "value2"} + + m.On("MSet", msetExpected).Return(nil) + err := i.Set("key1", []byte{1, 2, 3, 4, 5}, []string{"key2", "value2"}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestWriteByteArrayAsValue(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{"{namespace},key1", [5]byte{1, 2, 3, 4, 5}} + + m.On("MSet", msetExpected).Return(nil) + err := i.Set("key1", [5]byte{1, 2, 3, 4, 5}) + assert.Nil(t, err) + 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() + + msetExpected := []interface{}{"{namespace},key1", "data1", "{namespace},key2", "data2", "{namespace},key3", "data3"} + + m.On("MSet", msetExpected).Return(nil) + err := i.Set("key1", "data1", []string{"key2", "data2"}, [2]string{"key3", "data3"}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestWriteIncorrectMixed(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{"{namespace},key1", "data1", "{namespace},key2", "data2", "{namespace},key3", "data3"} + + m.AssertNotCalled(t, "MSet", msetExpected) + err := i.Set("key1", []string{"key2", "data2"}, [2]string{"key3", "data3"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} +func TestWriteIncorrectPairs(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{} + + m.AssertNotCalled(t, "MSet", msetExpected) + err := i.Set("key") + assert.NotNil(t, err) + m.AssertExpectations(t) +} func TestWriteSeveralKeysSlice(t *testing.T) { m, i := setup() @@ -173,6 +378,18 @@ func TestWriteSeveralKeysSlice(t *testing.T) { } +func TestWriteSeveralKeysIncorrectSlice(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{"{namespace},key1", "data1", "{namespace},key2", 22} + + m.AssertNotCalled(t, "MSet", msetExpected) + err := i.Set([]interface{}{"key1", "data1", "key2"}) + assert.NotNil(t, err) + m.AssertExpectations(t) + +} + func TestWriteSeveralKeysArray(t *testing.T) { m, i := setup() @@ -184,6 +401,17 @@ func TestWriteSeveralKeysArray(t *testing.T) { m.AssertExpectations(t) } +func TestWriteSeveralKeysIncorrectArray(t *testing.T) { + m, i := setup() + + msetExpected := []interface{}{} + + m.AssertNotCalled(t, "MSet", msetExpected) + err := i.Set([3]string{"key1", "data1", "key2"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} + func TestWriteFail(t *testing.T) { m, i := setup() @@ -204,6 +432,187 @@ func TestWriteEmptyList(t *testing.T) { m.AssertNotCalled(t, "MSet", msetExpected) } +func TestWriteAndPublishOneKeyOneChannel(t *testing.T) { + m, i := setup() + + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + expectedKeyVal := []interface{}{"{namespace},key1", "data1"} + + 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() + + expectedChannelAndEvents := []string{"{namespace},channel", "event1___event2"} + expectedKeyVal := []interface{}{"{namespace},key1", "data1"} + + 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) + m.AssertExpectations(t) +} + +func TestWriteAndPublishIncorrectChannelAndEvent(t *testing.T) { + m, i := setup() + + expectedChannelAndEvent := []string{} + expectedKeyVal := []interface{}{"{namespace},key1", "data1"} + m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal) + m.AssertNotCalled(t, "MSet", expectedKeyVal) + err := i.SetAndPublish([]string{"channel", "event1", "channel"}, "key1", "data1") + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestWriteAndPublishNotAllowedCharactersInEvents(t *testing.T) { + m, i := setup() + + expectedChannelAndEvent := []string{} + expectedKeyVal := []interface{}{"{namespace},key1", "data1"} + m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal) + m.AssertNotCalled(t, "MSet", expectedKeyVal) + err := i.SetAndPublish([]string{"channel", "event1___event2"}, "key1", "data1") + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestWriteAndPublishNoData(t *testing.T) { + m, i := setup() + + expectedChannelAndEvent := []string{} + expectedKeyVal := []interface{}{"key"} + + m.AssertNotCalled(t, "MSetMPub", expectedChannelAndEvent, expectedKeyVal) + m.AssertNotCalled(t, "MSet", expectedKeyVal) + err := i.SetAndPublish([]string{"channel", "event"}, []interface{}{"key"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestWriteAndPublishNoChannelEvent(t *testing.T) { + m, i := setup() + + expectedKeyVal := []interface{}{"{namespace},key1", "data1"} + + m.On("MSet", expectedKeyVal).Return(nil) + 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() + + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + expectedKeys := []string{"{namespace},key1", "{namespace},key2"} + + 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() + + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + expectedKeys := []string{"{namespace},key1", "{namespace},key2"} + + 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 TestRemoveAndPublishNoChannels(t *testing.T) { + m, i := setup() + + expectedKeys := []string{"{namespace},key1", "{namespace},key2"} + + m.On("Del", expectedKeys).Return(nil) + err := i.RemoveAndPublish([]string{}, []string{"key1", "key2"}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveAndPublishIncorrectChannel(t *testing.T) { + m, i := setup() + + notExpectedChannelAndEvent := []string{} + notExpectedKeys := []string{"{namespace},key"} + + m.AssertNotCalled(t, "DelMPub", notExpectedChannelAndEvent, notExpectedKeys) + m.AssertNotCalled(t, "Del", notExpectedKeys) + err := i.RemoveAndPublish([]string{"channel", "event", "channel2"}, []string{}) + assert.Nil(t, err) + m.AssertExpectations(t) + +} +func TestRemoveAndPublishNoKeys(t *testing.T) { + m, i := setup() + + notExpectedChannelAndEvent := []string{} + notExpectedKeys := []string{"{namespace},key"} + + m.AssertNotCalled(t, "DelMPub", notExpectedChannelAndEvent, notExpectedKeys) + m.AssertNotCalled(t, "Del", notExpectedKeys) + err := i.RemoveAndPublish([]string{"channel", "event"}, []string{}) + assert.Nil(t, err) + m.AssertExpectations(t) +} +func TestRemoveAndPublishNoChannelsError(t *testing.T) { + m, i := setup() + + expectedKeys := []string{"{namespace},key1", "{namespace},key2"} + + m.On("Del", expectedKeys).Return(errors.New("Some error")) + err := i.RemoveAndPublish([]string{}, []string{"key1", "key2"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} func TestRemoveSuccessfully(t *testing.T) { m, i := setup() @@ -356,80 +765,748 @@ func TestSetIfFailure(t *testing.T) { mSetIEExpectedKey := string("{namespace},key1") mSetIEExpectedOldData := interface{}("olddata") mSetIEExpectedNewData := interface{}("newdata") - m.On("SetIE", mSetIEExpectedKey, mSetIEExpectedOldData, mSetIEExpectedNewData).Return(true, errors.New("Some error")) + m.On("SetIE", mSetIEExpectedKey, mSetIEExpectedOldData, mSetIEExpectedNewData).Return(false, errors.New("Some error")) status, err := i.SetIf("key1", "olddata", "newdata") assert.NotNil(t, err) assert.False(t, status) m.AssertExpectations(t) } -func TestSetIfNotExistsSuccessfullyOkStatus(t *testing.T) { +func TestSetIfAndPublishSuccessfully(t *testing.T) { m, i := setup() - mSetNXExpectedKey := string("{namespace},key1") - mSetNXExpectedData := interface{}("data") - m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData).Return(true, nil) - status, err := i.SetIfNotExists("key1", "data") + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedOldData := interface{}("olddata") + expectedNewData := interface{}("newdata") + m.On("SetIEPub", expectedChannel, expectedEvent, expectedKey, expectedOldData, expectedNewData).Return(true, nil) + status, err := i.SetIfAndPublish([]string{"channel", "event"}, "key", "olddata", "newdata") assert.Nil(t, err) assert.True(t, status) m.AssertExpectations(t) } -func TestSetIfNotExistsSuccessfullyNOKStatus(t *testing.T) { +func TestSetIfAndPublishIncorrectChannelAndEvent(t *testing.T) { m, i := setup() - mSetNXExpectedKey := string("{namespace},key1") - mSetNXExpectedData := interface{}("data") - m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData).Return(false, nil) - status, err := i.SetIfNotExists("key1", "data") - assert.Nil(t, err) + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedOldData := interface{}("olddata") + expectedNewData := interface{}("newdata") + m.AssertNotCalled(t, "SetIEPub", expectedChannel, expectedEvent, expectedKey, expectedOldData, expectedNewData) + m.AssertNotCalled(t, "SetIE", expectedKey, expectedOldData, expectedNewData) + status, err := i.SetIfAndPublish([]string{"channel", "event1", "channel"}, "key", "olddata", "newdata") + assert.NotNil(t, err) assert.False(t, status) m.AssertExpectations(t) } - -func TestSetIfNotExistsFailure(t *testing.T) { +func TestSetIfAndPublishNOKStatus(t *testing.T) { m, i := setup() - mSetNXExpectedKey := string("{namespace},key1") - mSetNXExpectedData := interface{}("data") - m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData).Return(true, errors.New("Some error")) - status, err := i.SetIfNotExists("key1", "data") - assert.NotNil(t, err) + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedOldData := interface{}("olddata") + expectedNewData := interface{}("newdata") + m.On("SetIEPub", expectedChannel, expectedEvent, expectedKey, expectedOldData, expectedNewData).Return(false, nil) + status, err := i.SetIfAndPublish([]string{"channel", "event"}, "key", "olddata", "newdata") + assert.Nil(t, err) assert.False(t, status) m.AssertExpectations(t) } -func TestRemoveIfSuccessfullyOkStatus(t *testing.T) { + +func TestSetIfAndPublishNoChannels(t *testing.T) { m, i := setup() - mDelIEExpectedKey := string("{namespace},key1") - mDelIEExpectedData := interface{}("data") - m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(true, nil) - status, err := i.RemoveIf("key1", "data") + expectedKey := "{namespace},key" + expectedOldData := interface{}("olddata") + expectedNewData := interface{}("newdata") + m.On("SetIE", expectedKey, expectedOldData, expectedNewData).Return(true, nil) + status, err := i.SetIfAndPublish([]string{}, "key", "olddata", "newdata") assert.Nil(t, err) assert.True(t, status) m.AssertExpectations(t) } -func TestRemoveIfSuccessfullyNOKStatus(t *testing.T) { +func TestSetIfNotExistsAndPublishSuccessfully(t *testing.T) { m, i := setup() - mDelIEExpectedKey := string("{namespace},key1") - mDelIEExpectedData := interface{}("data") - m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(false, nil) - status, err := i.RemoveIf("key1", "data") + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.On("SetNXPub", expectedChannel, expectedEvent, expectedKey, expectedData).Return(true, nil) + status, err := i.SetIfNotExistsAndPublish([]string{"channel", "event"}, "key", "data") assert.Nil(t, err) - assert.False(t, status) + assert.True(t, status) m.AssertExpectations(t) } -func TestRemoveIfFailure(t *testing.T) { +func TestSetIfNotExistsAndPublishSeveralEvents(t *testing.T) { m, i := setup() - mDelIEExpectedKey := string("{namespace},key1") - mDelIEExpectedData := interface{}("data") - m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(true, errors.New("Some error")) - status, err := i.RemoveIf("key1", "data") - assert.NotNil(t, err) + expectedChannel := "{namespace},channel" + expectedEvent := "event1___event2" + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.On("SetNXPub", expectedChannel, expectedEvent, expectedKey, expectedData).Return(true, nil) + status, err := i.SetIfNotExistsAndPublish([]string{"channel", "event1", "channel", "event2"}, "key", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsAndPublishNoChannels(t *testing.T) { + m, i := setup() + + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.On("SetNX", expectedKey, expectedData, time.Duration(0)).Return(true, nil) + status, err := i.SetIfNotExistsAndPublish([]string{}, "key", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsAndPublishFail(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.On("SetNXPub", expectedChannel, expectedEvent, expectedKey, expectedData).Return(false, nil) + status, err := i.SetIfNotExistsAndPublish([]string{"channel", "event"}, "key", "data") + assert.Nil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsAndPublishIncorrectChannels(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.AssertNotCalled(t, "SetNXPub", expectedChannel, expectedEvent, expectedKey, expectedData) + m.AssertNotCalled(t, "SetNX", expectedKey, expectedData, 0) + status, err := i.SetIfNotExistsAndPublish([]string{"channel", "event", "channel2"}, "key", "data") + assert.NotNil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsAndPublishError(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedData := interface{}("data") + + m.On("SetNXPub", expectedChannel, expectedEvent, expectedKey, expectedData).Return(false, errors.New("Some error")) + status, err := i.SetIfNotExistsAndPublish([]string{"channel", "event"}, "key", "data") + assert.NotNil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsSuccessfullyOkStatus(t *testing.T) { + m, i := setup() + + mSetNXExpectedKey := string("{namespace},key1") + mSetNXExpectedData := interface{}("data") + m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData, time.Duration(0)).Return(true, nil) + status, err := i.SetIfNotExists("key1", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsSuccessfullyNOKStatus(t *testing.T) { + m, i := setup() + + mSetNXExpectedKey := string("{namespace},key1") + mSetNXExpectedData := interface{}("data") + m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData, time.Duration(0)).Return(false, nil) + status, err := i.SetIfNotExists("key1", "data") + assert.Nil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestSetIfNotExistsFailure(t *testing.T) { + m, i := setup() + + mSetNXExpectedKey := string("{namespace},key1") + mSetNXExpectedData := interface{}("data") + m.On("SetNX", mSetNXExpectedKey, mSetNXExpectedData, time.Duration(0)).Return(false, errors.New("Some error")) + status, err := i.SetIfNotExists("key1", "data") + assert.NotNil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfAndPublishSuccessfully(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event1___event2" + expectedKey := "{namespace},key" + expectedValue := interface{}("data") + + m.On("DelIEPub", expectedChannel, expectedEvent, expectedKey, expectedValue).Return(true, nil) + status, err := i.RemoveIfAndPublish([]string{"channel", "event1", "channel", "event2"}, "key", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfAndPublishNok(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event1___event2" + expectedKey := "{namespace},key" + expectedValue := interface{}("data") + + m.On("DelIEPub", expectedChannel, expectedEvent, expectedKey, expectedValue).Return(false, nil) + status, err := i.RemoveIfAndPublish([]string{"channel", "event1", "channel", "event2"}, "key", "data") + assert.Nil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfAndPublishError(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event1___event2" + expectedKey := "{namespace},key" + expectedValue := interface{}("data") + + m.On("DelIEPub", expectedChannel, expectedEvent, expectedKey, expectedValue).Return(false, errors.New("Some error")) + status, err := i.RemoveIfAndPublish([]string{"channel", "event1", "channel", "event2"}, "key", "data") + assert.NotNil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfAndPublishIncorrectChannel(t *testing.T) { + m, i := setup() + + expectedChannel := "{namespace},channel" + expectedEvent := "event" + expectedKey := "{namespace},key" + expectedValue := interface{}("data") + + m.AssertNotCalled(t, "DelIEPub", expectedChannel, expectedEvent, expectedKey, expectedValue) + m.AssertNotCalled(t, "DelIE", expectedKey, expectedValue) + status, err := i.RemoveIfAndPublish([]string{"channel", "event1", "channel"}, "key", "data") + assert.NotNil(t, err) assert.False(t, status) m.AssertExpectations(t) } + +func TestRemoveIfAndPublishNoChannels(t *testing.T) { + m, i := setup() + + expectedKey := "{namespace},key" + expectedValue := interface{}("data") + + m.On("DelIE", expectedKey, expectedValue).Return(true, nil) + status, err := i.RemoveIfAndPublish([]string{}, "key", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) + +} +func TestRemoveIfSuccessfullyOkStatus(t *testing.T) { + m, i := setup() + + mDelIEExpectedKey := string("{namespace},key1") + mDelIEExpectedData := interface{}("data") + m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(true, nil) + status, err := i.RemoveIf("key1", "data") + assert.Nil(t, err) + assert.True(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfSuccessfullyNOKStatus(t *testing.T) { + m, i := setup() + + mDelIEExpectedKey := string("{namespace},key1") + mDelIEExpectedData := interface{}("data") + m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(false, nil) + status, err := i.RemoveIf("key1", "data") + assert.Nil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestRemoveIfFailure(t *testing.T) { + m, i := setup() + + mDelIEExpectedKey := string("{namespace},key1") + mDelIEExpectedData := interface{}("data") + m.On("DelIE", mDelIEExpectedKey, mDelIEExpectedData).Return(true, errors.New("Some error")) + status, err := i.RemoveIf("key1", "data") + assert.NotNil(t, err) + assert.False(t, status) + m.AssertExpectations(t) +} + +func TestRemoveAllAndPublishSuccessfully(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + m.On("Keys", mKeysExpected).Return(mKeysReturn, nil) + m.On("DelMPub", expectedChannelAndEvent, mDelExpected).Return(nil) + err := i.RemoveAllAndPublish([]string{"channel", "event"}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveAllAndPublishKeysReturnError(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + m.On("Keys", mKeysExpected).Return(mKeysReturn, errors.New("Some error")) + m.AssertNotCalled(t, "DelMPub", expectedChannelAndEvent, mDelExpected) + err := i.RemoveAllAndPublish([]string{"channel", "event"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveAllAndPublishKeysDelReturnsError(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + m.On("Keys", mKeysExpected).Return(mKeysReturn, nil) + m.On("DelMPub", expectedChannelAndEvent, mDelExpected).Return(errors.New("Some error")) + err := i.RemoveAllAndPublish([]string{"channel", "event"}) + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveAllAndPublishKeysEventsWithIllegalCharacters(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + expectedChannelAndEvent := []string{"{namespace},channel", "event"} + m.On("Keys", mKeysExpected).Return(mKeysReturn, nil) + m.AssertNotCalled(t, "DelMPub", expectedChannelAndEvent, mDelExpected) + err := i.RemoveAllAndPublish([]string{"channel", "event___anotherEvent"}) + assert.NotNil(t, err) + m.AssertExpectations(t) + +} + +func TestRemoveAllAndPublishNoChannels(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + m.On("Keys", mKeysExpected).Return(mKeysReturn, nil) + m.On("Del", mDelExpected).Return(nil) + m.AssertNotCalled(t, "DelMPub", "", "", mDelExpected) + err := i.RemoveAllAndPublish([]string{}) + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveAllAndPublishIncorrectChannel(t *testing.T) { + m, i := setup() + + mKeysExpected := string("{namespace},*") + mKeysReturn := []string{"{namespace},key1", "{namespace},key2"} + mDelExpected := mKeysReturn + m.On("Keys", mKeysExpected).Return(mKeysReturn, nil) + m.AssertNotCalled(t, "DelMPub", "", "", mDelExpected) + err := i.RemoveAllAndPublish([]string{"channel", "event", "channel2"}) + assert.NotNil(t, err) + m.AssertExpectations(t) + +} + +func TestAddMemberSuccessfully(t *testing.T) { + m, i := setup() + + groupExpected := string("{namespace},group") + membersExpected := []interface{}{"member1", "member2"} + + m.On("SAdd", groupExpected, membersExpected).Return(nil) + + err := i.AddMember("group", "member1", "member2") + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestAddMemberFail(t *testing.T) { + m, i := setup() + + groupExpected := string("{namespace},group") + membersExpected := []interface{}{"member1", "member2"} + + m.On("SAdd", groupExpected, membersExpected).Return(errors.New("Some error")) + + err := i.AddMember("group", "member1", "member2") + assert.NotNil(t, err) + m.AssertExpectations(t) +} +func TestRemoveMemberSuccessfully(t *testing.T) { + m, i := setup() + + groupExpected := string("{namespace},group") + membersExpected := []interface{}{"member1", "member2"} + + m.On("SRem", groupExpected, membersExpected).Return(nil) + + err := i.RemoveMember("group", "member1", "member2") + assert.Nil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveMemberFail(t *testing.T) { + m, i := setup() + + groupExpected := string("{namespace},group") + membersExpected := []interface{}{"member1", "member2"} + + m.On("SRem", groupExpected, membersExpected).Return(errors.New("Some error")) + + err := i.RemoveMember("group", "member1", "member2") + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestRemoveGroupSuccessfully(t *testing.T) { + m, i := setup() + + groupExpected := []string{"{namespace},group"} + + m.On("Del", groupExpected).Return(nil) + + err := i.RemoveGroup("group") + assert.Nil(t, err) + m.AssertExpectations(t) +} +func TestRemoveGroupFail(t *testing.T) { + m, i := setup() + + groupExpected := []string{"{namespace},group"} + + m.On("Del", groupExpected).Return(errors.New("Some error")) + + err := i.RemoveGroup("group") + assert.NotNil(t, err) + m.AssertExpectations(t) +} + +func TestGetMembersSuccessfully(t *testing.T) { + m, i := setup() + + groupExpected := "{namespace},group" + returnExpected := []string{"member1", "member2"} + + m.On("SMembers", groupExpected).Return(returnExpected, nil) + + result, err := i.GetMembers("group") + assert.Nil(t, err) + assert.Equal(t, result, returnExpected) + m.AssertExpectations(t) +} +func TestGetMembersFail(t *testing.T) { + m, i := setup() + + groupExpected := "{namespace},group" + returnExpected := []string{"member1", "member2"} + + m.On("SMembers", groupExpected).Return(returnExpected, errors.New("Some error")) + + result, err := i.GetMembers("group") + assert.NotNil(t, err) + assert.Equal(t, []string{}, result) + m.AssertExpectations(t) +} + +func TestIsMemberSuccessfullyIsMember(t *testing.T) { + m, i := setup() + + groupExpected := "{namespace},group" + memberExpected := "member" + + m.On("SIsMember", groupExpected, memberExpected).Return(true, nil) + + result, err := i.IsMember("group", "member") + assert.Nil(t, err) + assert.True(t, result) + m.AssertExpectations(t) +} +func TestIsMemberSuccessfullyIsNotMember(t *testing.T) { + m, i := setup() + + groupExpected := "{namespace},group" + memberExpected := "member" + + m.On("SIsMember", groupExpected, memberExpected).Return(false, nil) + + result, err := i.IsMember("group", "member") + assert.Nil(t, err) + assert.False(t, result) + m.AssertExpectations(t) +} +func TestIsMemberFailure(t *testing.T) { + m, i := setup() + + groupExpected := "{namespace},group" + memberExpected := "member" + + m.On("SIsMember", groupExpected, memberExpected).Return(true, errors.New("Some error")) + + result, err := i.IsMember("group", "member") + assert.NotNil(t, err) + assert.False(t, result) + m.AssertExpectations(t) +} + +func TestGroupSizeSuccessfully(t *testing.T) { + m, i := setup() + + var expectedSize int64 + expectedSize = 2 + groupExpected := "{namespace},group" + + m.On("SCard", groupExpected).Return(expectedSize, nil) + + result, err := i.GroupSize("group") + assert.Nil(t, err) + assert.Equal(t, expectedSize, result) + m.AssertExpectations(t) +} +func TestGroupSizeFail(t *testing.T) { + m, i := setup() + + var expectedSize int64 + expectedSize = 2 + groupExpected := "{namespace},group" + + m.On("SCard", groupExpected).Return(expectedSize, errors.New("Some error")) + + result, err := i.GroupSize("group") + assert.NotNil(t, err) + assert.Equal(t, int64(0), result) + m.AssertExpectations(t) +} + +func TestLockResourceSuccessfully(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil) + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{}) + assert.Nil(t, err) + assert.NotNil(t, lock) + m.AssertExpectations(t) +} + +func TestLockResourceFailure(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, errors.New("Some error")) + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{}) + assert.NotNil(t, err) + assert.Nil(t, lock) + m.AssertExpectations(t) +} + +func TestLockResourceTrySeveralTimesSuccessfully(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(false, nil).Once() + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 2, + }) + assert.Nil(t, err) + assert.NotNil(t, lock) + m.AssertExpectations(t) +} + +func TestLockResourceTrySeveralTimesFailure(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(false, nil).Once() + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, errors.New("Some error")).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 2, + }) + assert.NotNil(t, err) + assert.Nil(t, lock) + m.AssertExpectations(t) +} + +func TestLockResourceTrySeveralTimesUnableToGetResource(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(false, nil).Once() + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(false, nil).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + assert.NotNil(t, err) + assert.EqualError(t, err, "Lock not obtained") + assert.Nil(t, lock) + m.AssertExpectations(t) +} + +func TestReleaseResourceSuccessfully(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + m.On("DelIE", resourceExpected, mock.Anything).Return(true, nil).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + err2 := lock.ReleaseResource() + assert.Nil(t, err) + assert.NotNil(t, lock) + assert.Nil(t, err2) + m.AssertExpectations(t) +} + +func TestReleaseResourceFailure(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + m.On("DelIE", resourceExpected, mock.Anything).Return(true, errors.New("Some error")).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + err2 := lock.ReleaseResource() + assert.Nil(t, err) + assert.NotNil(t, lock) + assert.NotNil(t, err2) + m.AssertExpectations(t) +} + +func TestReleaseResourceLockNotHeld(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + m.On("DelIE", resourceExpected, mock.Anything).Return(false, nil).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + err2 := lock.ReleaseResource() + assert.Nil(t, err) + assert.NotNil(t, lock) + assert.NotNil(t, err2) + assert.EqualError(t, err2, "Lock not held") + m.AssertExpectations(t) +} + +func TestRefreshResourceSuccessfully(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + m.On("PExpireIE", resourceExpected, mock.Anything, time.Duration(1)).Return(nil).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + err2 := lock.RefreshResource(time.Duration(1)) + assert.Nil(t, err) + assert.NotNil(t, lock) + assert.Nil(t, err2) + m.AssertExpectations(t) +} + +func TestRefreshResourceFailure(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("SetNX", resourceExpected, mock.Anything, time.Duration(1)).Return(true, nil).Once() + m.On("PExpireIE", resourceExpected, mock.Anything, time.Duration(1)).Return(errors.New("Some error")).Once() + + lock, err := i.LockResource("resource", time.Duration(1), &sdlgo.Options{ + RetryCount: 1, + }) + err2 := lock.RefreshResource(time.Duration(1)) + assert.Nil(t, err) + assert.NotNil(t, lock) + assert.NotNil(t, err2) + m.AssertExpectations(t) +} + +func TestCheckResourceSuccessfully(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("PTTL", resourceExpected).Return(time.Duration(1), nil) + result, err := i.CheckResource("resource") + assert.Nil(t, err) + assert.Equal(t, result, time.Duration(1)) + m.AssertExpectations(t) +} + +func TestCheckResourceFailure(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("PTTL", resourceExpected).Return(time.Duration(1), errors.New("Some error")) + result, err := i.CheckResource("resource") + assert.NotNil(t, err) + assert.EqualError(t, err, "Some error") + assert.Equal(t, result, time.Duration(0)) + m.AssertExpectations(t) +} + +func TestCheckResourceInvalidResource(t *testing.T) { + m, i := setup() + + resourceExpected := "{namespace},resource" + m.On("PTTL", resourceExpected).Return(time.Duration(-1), nil) + result, err := i.CheckResource("resource") + assert.NotNil(t, err) + assert.EqualError(t, err, "invalid resource given, no expiration time attached") + assert.Equal(t, result, time.Duration(0)) + m.AssertExpectations(t) +}