mirror of https://github.com/hashicorp/consul
361 lines
14 KiB
Go
361 lines
14 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package cache_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/hashicorp/consul/internal/controller/cache"
|
|
"github.com/hashicorp/consul/internal/controller/cache/cachemock"
|
|
"github.com/hashicorp/consul/internal/resource"
|
|
"github.com/hashicorp/consul/internal/resource/demo"
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v2"
|
|
"github.com/hashicorp/consul/proto/private/prototest"
|
|
)
|
|
|
|
type decodedSuite struct {
|
|
suite.Suite
|
|
rc *cachemock.ReadOnlyCache
|
|
iter *cachemock.ResourceIterator
|
|
|
|
artistGood *resource.DecodedResource[*pbdemo.Artist]
|
|
artistGood2 *resource.DecodedResource[*pbdemo.Artist]
|
|
artistBad *pbresource.Resource
|
|
}
|
|
|
|
func (suite *decodedSuite) SetupTest() {
|
|
suite.rc = cachemock.NewReadOnlyCache(suite.T())
|
|
suite.iter = cachemock.NewResourceIterator(suite.T())
|
|
artist, err := demo.GenerateV2Artist()
|
|
require.NoError(suite.T(), err)
|
|
suite.artistGood, err = resource.Decode[*pbdemo.Artist](artist)
|
|
require.NoError(suite.T(), err)
|
|
|
|
artist2, err := demo.GenerateV2Artist()
|
|
require.NoError(suite.T(), err)
|
|
suite.artistGood2, err = resource.Decode[*pbdemo.Artist](artist2)
|
|
require.NoError(suite.T(), err)
|
|
|
|
suite.artistBad, err = demo.GenerateV2Album(artist.Id)
|
|
require.NoError(suite.T(), err)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestGetDecoded_Ok() {
|
|
suite.rc.EXPECT().Get(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(suite.artistGood.Resource, nil)
|
|
|
|
dec, err := cache.GetDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestGetDecoded_DecodeError() {
|
|
suite.rc.EXPECT().Get(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(suite.artistBad, nil)
|
|
|
|
dec, err := cache.GetDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestGetDecoded_CacheError() {
|
|
suite.rc.EXPECT().Get(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, injectedError)
|
|
|
|
dec, err := cache.GetDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestGetDecoded_Nil() {
|
|
suite.rc.EXPECT().Get(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, nil)
|
|
|
|
dec, err := cache.GetDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListDecoded_Ok() {
|
|
suite.rc.EXPECT().List(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return([]*pbresource.Resource{suite.artistGood.Resource, suite.artistGood2.Resource}, nil)
|
|
|
|
dec, err := cache.ListDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Len(suite.T(), dec, 2)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec[0].Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec[0].Data)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Resource, dec[1].Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Data, dec[1].Data)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListDecoded_DecodeError() {
|
|
suite.rc.EXPECT().List(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return([]*pbresource.Resource{suite.artistGood.Resource, suite.artistBad}, nil)
|
|
|
|
dec, err := cache.ListDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListDecoded_CacheError() {
|
|
suite.rc.EXPECT().List(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, injectedError)
|
|
|
|
dec, err := cache.ListDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListDecoded_Nil() {
|
|
suite.rc.EXPECT().List(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, nil)
|
|
|
|
dec, err := cache.ListDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListIteratorDecoded_Ok() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood2.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().ListIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.ListIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListIteratorDecoded_DecodeError() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistBad).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().ListIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.ListIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListIteratorDecoded_CacheError() {
|
|
suite.rc.EXPECT().ListIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, injectedError)
|
|
|
|
iter, err := cache.ListIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), iter)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestListIteratorDecoded_Nil() {
|
|
suite.rc.EXPECT().ListIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, nil)
|
|
|
|
dec, err := cache.ListIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsDecoded_Ok() {
|
|
suite.rc.EXPECT().Parents(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return([]*pbresource.Resource{suite.artistGood.Resource, suite.artistGood2.Resource}, nil)
|
|
|
|
dec, err := cache.ParentsDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Len(suite.T(), dec, 2)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec[0].Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec[0].Data)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Resource, dec[1].Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Data, dec[1].Data)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsDecoded_DecodeError() {
|
|
suite.rc.EXPECT().Parents(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return([]*pbresource.Resource{suite.artistGood.Resource, suite.artistBad}, nil)
|
|
|
|
dec, err := cache.ParentsDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsDecoded_CacheError() {
|
|
suite.rc.EXPECT().Parents(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, injectedError)
|
|
|
|
dec, err := cache.ParentsDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsDecoded_Nil() {
|
|
suite.rc.EXPECT().Parents(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, nil)
|
|
|
|
dec, err := cache.ParentsDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsIteratorDecoded_Ok() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood2.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().ParentsIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.ParentsIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsIteratorDecoded_DecodeError() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistBad).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().ParentsIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.ParentsIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsIteratorDecoded_CacheError() {
|
|
suite.rc.EXPECT().ParentsIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, injectedError)
|
|
|
|
iter, err := cache.ParentsIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), iter)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestParentsIteratorDecoded_Nil() {
|
|
suite.rc.EXPECT().ParentsIterator(pbdemo.ArtistType, "id", suite.artistGood.Id).Return(nil, nil)
|
|
|
|
dec, err := cache.ParentsIteratorDecoded[*pbdemo.Artist](suite.rc, pbdemo.ArtistType, "id", suite.artistGood.Id)
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestQueryDecoded_Ok() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood2.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().Query("query", "blah").
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.QueryDecoded[*pbdemo.Artist](suite.rc, "query", "blah")
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood2.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestQueryDecoded_DecodeError() {
|
|
suite.iter.EXPECT().Next().Return(suite.artistGood.Resource).Once()
|
|
suite.iter.EXPECT().Next().Return(suite.artistBad).Once()
|
|
suite.iter.EXPECT().Next().Return(nil).Times(0)
|
|
suite.rc.EXPECT().Query("query", "blah").
|
|
Return(suite.iter, nil)
|
|
|
|
iter, err := cache.QueryDecoded[*pbdemo.Artist](suite.rc, "query", "blah")
|
|
require.NoError(suite.T(), err)
|
|
require.NotNil(suite.T(), iter)
|
|
|
|
dec, err := iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Resource, dec.Resource)
|
|
prototest.AssertDeepEqual(suite.T(), suite.artistGood.Data, dec.Data)
|
|
|
|
dec, err = iter.Next()
|
|
require.Error(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
|
|
dec, err = iter.Next()
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestQueryDecoded_CacheError() {
|
|
suite.rc.EXPECT().Query("query", "blah").Return(nil, injectedError)
|
|
|
|
dec, err := cache.QueryDecoded[*pbdemo.Artist](suite.rc, "query", "blah")
|
|
require.ErrorIs(suite.T(), err, injectedError)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func (suite *decodedSuite) TestQueryDecoded_Nil() {
|
|
suite.rc.EXPECT().Query("query", "blah").Return(nil, nil)
|
|
|
|
dec, err := cache.QueryDecoded[*pbdemo.Artist](suite.rc, "query", "blah")
|
|
require.NoError(suite.T(), err)
|
|
require.Nil(suite.T(), dec)
|
|
}
|
|
|
|
func TestDecodedCache(t *testing.T) {
|
|
suite.Run(t, new(decodedSuite))
|
|
}
|