292 lines
7.5 KiB
Go
292 lines
7.5 KiB
Go
// Copyright (c) Mainflux
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package events_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/mainflux/mainflux/twins"
|
|
"github.com/mainflux/mainflux/twins/events"
|
|
"github.com/mainflux/mainflux/twins/mocks"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var (
|
|
subtopics = []string{"engine", "chassis", "wheel_2"}
|
|
channels = []string{"01ec3c3e-0e66-4e69-9751-a0545b44e08f", "48061e4f-7c23-4f5c-9012-0f9b7cd9d18d", "5b2180e4-e96b-4469-9dc1-b6745078d0b6"}
|
|
)
|
|
|
|
func TestTwinSave(t *testing.T) {
|
|
redisClient.FlushAll(context.Background())
|
|
twinCache := events.NewTwinCache(redisClient)
|
|
|
|
twin1 := mocks.CreateTwin(channels[0:2], subtopics[0:2])
|
|
twin2 := mocks.CreateTwin(channels[1:3], subtopics[1:3])
|
|
|
|
cases := []struct {
|
|
desc string
|
|
twin twins.Twin
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Save twin to cache",
|
|
twin: twin1,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save already cached twin to cache",
|
|
twin: twin1,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save another twin to cache",
|
|
twin: twin2,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save already cached twin to cache",
|
|
twin: twin2,
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
ctx := context.Background()
|
|
err := twinCache.Save(ctx, tc.twin)
|
|
assert.Nil(t, err, fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.err, err))
|
|
|
|
def := tc.twin.Definitions[len(tc.twin.Definitions)-1]
|
|
for _, attr := range def.Attributes {
|
|
ids, err := twinCache.IDs(ctx, attr.Channel, attr.Subtopic)
|
|
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
assert.Contains(t, ids, tc.twin.ID, fmt.Sprintf("%s: id %s not found in %v", tc.desc, tc.twin.ID, ids))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTwinSaveIDs(t *testing.T) {
|
|
redisClient.FlushAll(context.Background())
|
|
twinCache := events.NewTwinCache(redisClient)
|
|
|
|
twinIDs := []string{"7956f132-0b42-488d-9bd1-0f6dd9d77f98", "a2210c42-1eaf-41ad-b8c1-813317719ed9", "6e815c79-a159-41b0-9ff0-cfa14430e07e"}
|
|
|
|
cases := []struct {
|
|
desc string
|
|
channel string
|
|
subtopic string
|
|
ids []string
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Save ids to cache",
|
|
channel: channels[0],
|
|
subtopic: subtopics[0],
|
|
ids: twinIDs,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save empty ids array to cache",
|
|
channel: channels[2],
|
|
subtopic: subtopics[2],
|
|
ids: []string{},
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save already saved ids to cache",
|
|
channel: channels[0],
|
|
subtopic: subtopics[0],
|
|
ids: twinIDs,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save ids to cache",
|
|
channel: channels[1],
|
|
subtopic: subtopics[1],
|
|
ids: twinIDs[0:2],
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
ctx := context.Background()
|
|
err := twinCache.SaveIDs(ctx, tc.channel, tc.subtopic, tc.ids)
|
|
assert.Nil(t, err, fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.err, err))
|
|
|
|
ids, err := twinCache.IDs(ctx, tc.channel, tc.subtopic)
|
|
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
assert.ElementsMatch(t, ids, tc.ids, fmt.Sprintf("%s: got incorrect ids", tc.desc))
|
|
}
|
|
}
|
|
|
|
func TestTwinUpdate(t *testing.T) {
|
|
redisClient.FlushAll(context.Background())
|
|
twinCache := events.NewTwinCache(redisClient)
|
|
ctx := context.Background()
|
|
|
|
var tws []twins.Twin
|
|
for i := range channels {
|
|
tw := mocks.CreateTwin(channels[i:i+1], subtopics[i:i+1])
|
|
tws = append(tws, tw)
|
|
}
|
|
err := twinCache.Save(ctx, tws[0])
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
tws[1].ID = tws[0].ID
|
|
|
|
cases := []struct {
|
|
desc string
|
|
twinID string
|
|
twin twins.Twin
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Update saved twin",
|
|
twinID: tws[0].ID,
|
|
twin: tws[1],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Update twin with same definition",
|
|
twinID: tws[0].ID,
|
|
twin: tws[1],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Update unsaved twin definition",
|
|
twinID: tws[2].ID,
|
|
twin: tws[2],
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
err := twinCache.Update(ctx, tc.twin)
|
|
assert.Nil(t, err, fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.err, err))
|
|
|
|
attr := tc.twin.Definitions[0].Attributes[0]
|
|
ids, err := twinCache.IDs(ctx, attr.Channel, attr.Subtopic)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
assert.Contains(t, ids, tc.twinID, fmt.Sprintf("%s: the list doesn't contain the correct elements", tc.desc))
|
|
}
|
|
}
|
|
|
|
func TestTwinIDs(t *testing.T) {
|
|
redisClient.FlushAll(context.Background())
|
|
twinCache := events.NewTwinCache(redisClient)
|
|
ctx := context.Background()
|
|
|
|
var tws []twins.Twin
|
|
for i := 0; i < len(channels); i++ {
|
|
tw := mocks.CreateTwin(channels[0:1], subtopics[0:1])
|
|
err := twinCache.Save(ctx, tw)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
tws = append(tws, tw)
|
|
}
|
|
for i := 0; i < len(channels); i++ {
|
|
tw := mocks.CreateTwin(channels[1:2], subtopics[1:2])
|
|
err := twinCache.Save(ctx, tw)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
tws = append(tws, tw)
|
|
}
|
|
twEmptySubt := mocks.CreateTwin(channels[0:1], []string{""})
|
|
err := twinCache.Save(ctx, twEmptySubt)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
twSubtWild := mocks.CreateTwin(channels[0:1], []string{twins.SubtopicWildcard})
|
|
err = twinCache.Save(ctx, twSubtWild)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
|
|
nonExistAttr := twins.Attribute{
|
|
Channel: channels[2],
|
|
Subtopic: subtopics[2],
|
|
PersistState: true,
|
|
}
|
|
|
|
cases := []struct {
|
|
desc string
|
|
ids []string
|
|
attr twins.Attribute
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Get twin IDs from cache for empty subtopic attribute",
|
|
ids: []string{twEmptySubt.ID, twSubtWild.ID},
|
|
attr: twEmptySubt.Definitions[0].Attributes[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Get twin IDs from cache for subset of ids",
|
|
ids: []string{tws[0].ID, tws[1].ID, tws[2].ID, twSubtWild.ID},
|
|
attr: tws[0].Definitions[0].Attributes[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Get twin IDs from cache for subset of ids",
|
|
ids: []string{tws[3].ID, tws[4].ID, tws[5].ID},
|
|
attr: tws[3].Definitions[0].Attributes[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Get twin IDs from cache for non existing attribute",
|
|
ids: []string{},
|
|
attr: nonExistAttr,
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
ids, err := twinCache.IDs(ctx, tc.attr.Channel, tc.attr.Subtopic)
|
|
assert.Nil(t, err, fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.err, err))
|
|
assert.ElementsMatch(t, ids, tc.ids, fmt.Sprintf("%s: got unexpected list of IDs", tc.desc))
|
|
}
|
|
}
|
|
|
|
func TestTwinRemove(t *testing.T) {
|
|
redisClient.FlushAll(context.Background())
|
|
twinCache := events.NewTwinCache(redisClient)
|
|
ctx := context.Background()
|
|
|
|
var tws []twins.Twin
|
|
for i := range channels {
|
|
tw := mocks.CreateTwin(channels[i:i+1], subtopics[i:i+1])
|
|
err := twinCache.Save(ctx, tw)
|
|
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
|
|
tws = append(tws, tw)
|
|
}
|
|
|
|
cases := []struct {
|
|
desc string
|
|
twin twins.Twin
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Remove twin from cache",
|
|
twin: tws[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Remove already removed twin from cache",
|
|
twin: tws[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Remove another twin from cache",
|
|
twin: tws[1],
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
err := twinCache.Remove(ctx, tc.twin.ID)
|
|
assert.Nil(t, err, fmt.Sprintf("%s: expected %s got %s", tc.desc, tc.err, err))
|
|
|
|
def := tc.twin.Definitions[len(tc.twin.Definitions)-1]
|
|
for _, attr := range def.Attributes {
|
|
ids, err := twinCache.IDs(ctx, attr.Channel, attr.Subtopic)
|
|
assert.Nil(t, err, fmt.Sprintf("unexpected error: %s\n", err))
|
|
assert.NotContains(t, ids, tc.twin.ID, fmt.Sprintf("%s: found unexpected ID in the list", tc.desc))
|
|
}
|
|
}
|
|
}
|