github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/dispatch/graph/dispatch_test.go (about)

     1  package graph
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/authzed/spicedb/internal/dispatch"
     9  	"github.com/authzed/spicedb/internal/graph"
    10  	core "github.com/authzed/spicedb/pkg/proto/core/v1"
    11  	v1 "github.com/authzed/spicedb/pkg/proto/dispatch/v1"
    12  	"github.com/authzed/spicedb/pkg/tuple"
    13  
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestDispatchChunking(t *testing.T) {
    18  	schema := `
    19  		definition user {
    20  			relation self: user
    21  		}
    22  
    23  		definition res {
    24  			relation owner : user
    25  			permission view = owner->self
    26  		}`
    27  
    28  	resources := make([]*core.RelationTuple, 0, math.MaxUint16+1)
    29  	enabled := make([]*core.RelationTuple, 0, math.MaxUint16+1)
    30  	for i := 0; i < math.MaxUint16+1; i++ {
    31  		resources = append(resources, tuple.Parse(fmt.Sprintf("res:res1#owner@user:user%d", i)))
    32  		enabled = append(enabled, tuple.Parse(fmt.Sprintf("user:user%d#self@user:user%d", i, i)))
    33  	}
    34  
    35  	ctx, dispatcher, revision := newLocalDispatcherWithSchemaAndRels(t, schema, append(enabled, resources...))
    36  
    37  	t.Run("check", func(t *testing.T) {
    38  		for _, tpl := range resources[:1] {
    39  			checkResult, err := dispatcher.DispatchCheck(ctx, &v1.DispatchCheckRequest{
    40  				ResourceRelation: RR(tpl.ResourceAndRelation.Namespace, "view"),
    41  				ResourceIds:      []string{tpl.ResourceAndRelation.ObjectId},
    42  				ResultsSetting:   v1.DispatchCheckRequest_ALLOW_SINGLE_RESULT,
    43  				Subject:          ONR(tpl.Subject.Namespace, tpl.Subject.ObjectId, graph.Ellipsis),
    44  				Metadata: &v1.ResolverMeta{
    45  					AtRevision:     revision.String(),
    46  					DepthRemaining: 50,
    47  				},
    48  			})
    49  
    50  			require.NoError(t, err)
    51  			require.NotNil(t, checkResult)
    52  			require.NotEmpty(t, checkResult.ResultsByResourceId, "expected membership for resource %s", tpl.ResourceAndRelation.ObjectId)
    53  			require.Equal(t, v1.ResourceCheckResult_MEMBER, checkResult.ResultsByResourceId[tpl.ResourceAndRelation.ObjectId].Membership)
    54  		}
    55  	})
    56  
    57  	t.Run("lookup-resources", func(t *testing.T) {
    58  		for _, tpl := range resources[:1] {
    59  			stream := dispatch.NewCollectingDispatchStream[*v1.DispatchLookupResourcesResponse](ctx)
    60  			err := dispatcher.DispatchLookupResources(&v1.DispatchLookupResourcesRequest{
    61  				ObjectRelation: RR(tpl.ResourceAndRelation.Namespace, "view"),
    62  				Subject:        ONR(tpl.Subject.Namespace, tpl.Subject.ObjectId, graph.Ellipsis),
    63  				Metadata: &v1.ResolverMeta{
    64  					AtRevision:     revision.String(),
    65  					DepthRemaining: 50,
    66  				},
    67  				OptionalLimit: veryLargeLimit,
    68  			}, stream)
    69  
    70  			require.NoError(t, err)
    71  
    72  			foundResources, _, _, _ := processResults(stream)
    73  			require.Len(t, foundResources, 1)
    74  		}
    75  	})
    76  
    77  	t.Run("lookup-subjects", func(t *testing.T) {
    78  		for _, tpl := range resources[:1] {
    79  			stream := dispatch.NewCollectingDispatchStream[*v1.DispatchLookupSubjectsResponse](ctx)
    80  
    81  			err := dispatcher.DispatchLookupSubjects(&v1.DispatchLookupSubjectsRequest{
    82  				ResourceRelation: RR(tpl.ResourceAndRelation.Namespace, "view"),
    83  				ResourceIds:      []string{tpl.ResourceAndRelation.ObjectId},
    84  				SubjectRelation:  RR(tpl.Subject.Namespace, graph.Ellipsis),
    85  				Metadata: &v1.ResolverMeta{
    86  					AtRevision:     revision.String(),
    87  					DepthRemaining: 50,
    88  				},
    89  			}, stream)
    90  
    91  			require.NoError(t, err)
    92  			res := stream.Results()
    93  			require.Len(t, res, 1)
    94  			require.Len(t, res[0].FoundSubjectsByResourceId, 1)
    95  			require.NotNil(t, res[0].FoundSubjectsByResourceId["res1"])
    96  			require.Len(t, res[0].FoundSubjectsByResourceId["res1"].FoundSubjects, math.MaxUint16+1)
    97  		}
    98  	})
    99  }