2023-08-01 18:39:15 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-08-01 18:39:15 +00:00
|
|
|
|
|
|
|
package resource_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
|
|
|
2023-08-09 16:02:17 +00:00
|
|
|
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
2023-08-01 18:39:15 +00:00
|
|
|
"github.com/hashicorp/consul/internal/resource"
|
|
|
|
"github.com/hashicorp/consul/internal/resource/demo"
|
2023-08-09 16:02:17 +00:00
|
|
|
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
2023-08-01 18:39:15 +00:00
|
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
|
|
pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v2"
|
|
|
|
"github.com/hashicorp/consul/proto/private/prototest"
|
2023-08-09 16:02:17 +00:00
|
|
|
"github.com/hashicorp/consul/sdk/testutil"
|
2023-08-01 18:39:15 +00:00
|
|
|
)
|
|
|
|
|
2023-08-09 16:02:17 +00:00
|
|
|
func TestGetDecodedResource(t *testing.T) {
|
|
|
|
var (
|
2023-12-05 19:00:06 +00:00
|
|
|
baseClient = svctest.NewResourceServiceBuilder().WithRegisterFns(demo.RegisterTypes).Run(t)
|
2023-08-09 16:02:17 +00:00
|
|
|
client = rtest.NewClient(baseClient)
|
|
|
|
ctx = testutil.TestContext(t)
|
|
|
|
)
|
|
|
|
|
|
|
|
babypantsID := &pbresource.ID{
|
|
|
|
Type: demo.TypeV2Artist,
|
2023-08-24 15:49:46 +00:00
|
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
2023-08-09 16:02:17 +00:00
|
|
|
Name: "babypants",
|
|
|
|
}
|
|
|
|
|
|
|
|
testutil.RunStep(t, "not found", func(t *testing.T) {
|
2023-08-22 00:20:19 +00:00
|
|
|
got, err := resource.GetDecodedResource[*pbdemo.Artist](ctx, client, babypantsID)
|
2023-08-09 16:02:17 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, got)
|
|
|
|
})
|
|
|
|
|
|
|
|
testutil.RunStep(t, "found", func(t *testing.T) {
|
|
|
|
data := &pbdemo.Artist{
|
|
|
|
Name: "caspar babypants",
|
|
|
|
}
|
|
|
|
res := rtest.Resource(demo.TypeV2Artist, "babypants").
|
2023-09-01 14:44:53 +00:00
|
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
2023-08-09 16:02:17 +00:00
|
|
|
WithData(t, data).
|
|
|
|
Write(t, client)
|
|
|
|
|
2023-08-22 00:20:19 +00:00
|
|
|
got, err := resource.GetDecodedResource[*pbdemo.Artist](ctx, client, babypantsID)
|
2023-08-09 16:02:17 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, got)
|
|
|
|
|
|
|
|
// Clone generated fields over.
|
|
|
|
res.Id.Uid = got.Resource.Id.Uid
|
|
|
|
res.Version = got.Resource.Version
|
|
|
|
res.Generation = got.Resource.Generation
|
|
|
|
|
|
|
|
// Clone defaulted fields over
|
|
|
|
data.Genre = pbdemo.Genre_GENRE_DISCO
|
|
|
|
|
|
|
|
prototest.AssertDeepEqual(t, res, got.Resource)
|
|
|
|
prototest.AssertDeepEqual(t, data, got.Data)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-08-01 18:39:15 +00:00
|
|
|
func TestDecode(t *testing.T) {
|
|
|
|
t.Run("good", func(t *testing.T) {
|
|
|
|
fooData := &pbdemo.Artist{
|
|
|
|
Name: "caspar babypants",
|
|
|
|
}
|
|
|
|
any, err := anypb.New(fooData)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
foo := &pbresource.Resource{
|
|
|
|
Id: &pbresource.ID{
|
|
|
|
Type: demo.TypeV2Artist,
|
2023-08-24 15:49:46 +00:00
|
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
2023-08-01 18:39:15 +00:00
|
|
|
Name: "babypants",
|
|
|
|
},
|
|
|
|
Data: any,
|
|
|
|
Metadata: map[string]string{
|
|
|
|
"generated_at": time.Now().Format(time.RFC3339),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-08-22 00:20:19 +00:00
|
|
|
dec, err := resource.Decode[*pbdemo.Artist](foo)
|
2023-08-01 18:39:15 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
prototest.AssertDeepEqual(t, foo, dec.Resource)
|
|
|
|
prototest.AssertDeepEqual(t, fooData, dec.Data)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("bad", func(t *testing.T) {
|
|
|
|
foo := &pbresource.Resource{
|
|
|
|
Id: &pbresource.ID{
|
|
|
|
Type: demo.TypeV2Artist,
|
2023-08-24 15:49:46 +00:00
|
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
2023-08-01 18:39:15 +00:00
|
|
|
Name: "babypants",
|
|
|
|
},
|
|
|
|
Data: &anypb.Any{
|
|
|
|
TypeUrl: "garbage",
|
|
|
|
Value: []byte("more garbage"),
|
|
|
|
},
|
|
|
|
Metadata: map[string]string{
|
|
|
|
"generated_at": time.Now().Format(time.RFC3339),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-08-22 00:20:19 +00:00
|
|
|
_, err := resource.Decode[*pbdemo.Artist](foo)
|
2023-08-01 18:39:15 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
})
|
|
|
|
}
|
2024-01-18 22:52:52 +00:00
|
|
|
|
|
|
|
func TestDecodeList(t *testing.T) {
|
|
|
|
t.Run("good", func(t *testing.T) {
|
|
|
|
artist1, err := demo.GenerateV2Artist()
|
|
|
|
require.NoError(t, err)
|
|
|
|
artist2, err := demo.GenerateV2Artist()
|
|
|
|
require.NoError(t, err)
|
|
|
|
dec1, err := resource.Decode[*pbdemo.Artist](artist1)
|
|
|
|
require.NoError(t, err)
|
|
|
|
dec2, err := resource.Decode[*pbdemo.Artist](artist2)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
resources := []*pbresource.Resource{artist1, artist2}
|
|
|
|
|
|
|
|
decList, err := resource.DecodeList[*pbdemo.Artist](resources)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, decList, 2)
|
|
|
|
|
|
|
|
prototest.AssertDeepEqual(t, dec1.Resource, decList[0].Resource)
|
|
|
|
prototest.AssertDeepEqual(t, dec1.Data, decList[0].Data)
|
|
|
|
prototest.AssertDeepEqual(t, dec2.Resource, decList[1].Resource)
|
|
|
|
prototest.AssertDeepEqual(t, dec2.Data, decList[1].Data)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("bad", func(t *testing.T) {
|
|
|
|
artist1, err := demo.GenerateV2Artist()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
foo := &pbresource.Resource{
|
|
|
|
Id: &pbresource.ID{
|
|
|
|
Type: demo.TypeV2Artist,
|
|
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
|
|
|
Name: "babypants",
|
|
|
|
},
|
|
|
|
Data: &anypb.Any{
|
|
|
|
TypeUrl: "garbage",
|
|
|
|
Value: []byte("more garbage"),
|
|
|
|
},
|
|
|
|
Metadata: map[string]string{
|
|
|
|
"generated_at": time.Now().Format(time.RFC3339),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = resource.DecodeList[*pbdemo.Artist]([]*pbresource.Resource{artist1, foo})
|
|
|
|
require.Error(t, err)
|
|
|
|
})
|
|
|
|
}
|