From 69be4c975a744aa03326f881fa0412ce4578d4d4 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Wed, 29 Jan 2025 11:04:20 -0700 Subject: [PATCH 1/2] Fix import behavior --- internal/cmd/import.go | 7 ++++--- internal/decode/decoder.go | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/cmd/import.go b/internal/cmd/import.go index d312cbe..fdc87ff 100644 --- a/internal/cmd/import.go +++ b/internal/cmd/import.go @@ -9,6 +9,7 @@ import ( v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" "github.com/authzed/spicedb/pkg/tuple" + "github.com/authzed/spicedb/pkg/validationfile" "github.com/jzelinskie/cobrautil/v2" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -76,7 +77,7 @@ func importCmdFunc(cmd *cobra.Command, args []string) error { if err != nil { return err } - var p decode.SchemaRelationships + var p validationfile.ValidationFile if _, _, err := decoder(&p); err != nil { return err } @@ -87,7 +88,7 @@ func importCmdFunc(cmd *cobra.Command, args []string) error { } if cobrautil.MustGetBool(cmd, "schema") { - if err := importSchema(cmd.Context(), client, p.Schema, prefix); err != nil { + if err := importSchema(cmd.Context(), client, p.Schema.Schema, prefix); err != nil { return err } } @@ -95,7 +96,7 @@ func importCmdFunc(cmd *cobra.Command, args []string) error { if cobrautil.MustGetBool(cmd, "relationships") { batchSize := cobrautil.MustGetInt(cmd, "batch-size") workers := cobrautil.MustGetInt(cmd, "workers") - if err := importRelationships(cmd.Context(), client, p.Relationships, prefix, batchSize, workers); err != nil { + if err := importRelationships(cmd.Context(), client, p.Relationships.RelationshipsString, prefix, batchSize, workers); err != nil { return err } } diff --git a/internal/decode/decoder.go b/internal/decode/decoder.go index e7b3bdb..5781e41 100644 --- a/internal/decode/decoder.go +++ b/internal/decode/decoder.go @@ -113,7 +113,10 @@ func unmarshalAsYAMLOrSchemaWithFile(data []byte, out interface{}, filename stri if err := yaml.Unmarshal(data, out); err != nil { return false, err } - validationFile := out.(*validationfile.ValidationFile) + validationFile, ok := out.(*validationfile.ValidationFile) + if !ok { + return false, fmt.Errorf("could not cast unmarshalled file to validationfile") + } // Need to join the original filepath with the requested filepath // to construct the path to the referenced schema file. From 5dd489f4fb3210da0e9ee27be0106db4162a8792 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Wed, 29 Jan 2025 13:26:30 -0700 Subject: [PATCH 2/2] Add test for import behavior --- internal/cmd/import_test.go | 62 +++++++++++++++++++ .../cmd/test/happy-path-validation-file.yaml | 9 +++ .../cmd/test/happy-path-validation-schema.zed | 6 ++ 3 files changed, 77 insertions(+) create mode 100644 internal/cmd/import_test.go create mode 100644 internal/cmd/test/happy-path-validation-file.yaml create mode 100644 internal/cmd/test/happy-path-validation-schema.zed diff --git a/internal/cmd/import_test.go b/internal/cmd/import_test.go new file mode 100644 index 0000000..8739c21 --- /dev/null +++ b/internal/cmd/import_test.go @@ -0,0 +1,62 @@ +package cmd + +import ( + "context" + "path/filepath" + "testing" + + v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" + "github.com/stretchr/testify/require" + + "github.com/authzed/zed/internal/client" + zedtesting "github.com/authzed/zed/internal/testing" +) + +var fullyConsistent = &v1.Consistency{Requirement: &v1.Consistency_FullyConsistent{FullyConsistent: true}} + +func TestImportCmdHappyPath(t *testing.T) { + require := require.New(t) + cmd := zedtesting.CreateTestCobraCommandWithFlagValue(t, + zedtesting.StringFlag{FlagName: "schema-definition-prefix"}, + zedtesting.BoolFlag{FlagName: "schema", FlagValue: true}, + zedtesting.BoolFlag{FlagName: "relationships", FlagValue: true}, + zedtesting.IntFlag{FlagName: "batch-size", FlagValue: 100}, + zedtesting.IntFlag{FlagName: "workers", FlagValue: 1}, + ) + f := filepath.Join("test", "happy-path-validation-file.yaml") + + // Set up client + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + srv := zedtesting.NewTestServer(ctx, t) + go func() { + require.NoError(srv.Run(ctx)) + }() + conn, err := srv.GRPCDialContext(ctx) + require.NoError(err) + + originalClient := client.NewClient + defer func() { + client.NewClient = originalClient + }() + + client.NewClient = zedtesting.ClientFromConn(conn) + + c, err := zedtesting.ClientFromConn(conn)(cmd) + require.NoError(err) + + // Run the import and assert we don't have errors + err = importCmdFunc(cmd, []string{f}) + require.NoError(err) + + // Run a check with full consistency to see whether the relationships + // and schema are written + resp, err := c.CheckPermission(ctx, &v1.CheckPermissionRequest{ + Consistency: fullyConsistent, + Subject: &v1.SubjectReference{Object: &v1.ObjectReference{ObjectType: "user", ObjectId: "1"}}, + Permission: "view", + Resource: &v1.ObjectReference{ObjectType: "resource", ObjectId: "1"}, + }) + require.NoError(err) + require.Equal(resp.Permissionship, v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION) +} diff --git a/internal/cmd/test/happy-path-validation-file.yaml b/internal/cmd/test/happy-path-validation-file.yaml new file mode 100644 index 0000000..a193cee --- /dev/null +++ b/internal/cmd/test/happy-path-validation-file.yaml @@ -0,0 +1,9 @@ +--- +schemaFile: "./happy-path-validation-schema.zed" +relationships: >- + resource:1#user@user:1 +assertions: + assertTrue: + - "resource:1#user@user:1" + assertFalse: + - "resource:1#user@user:2" diff --git a/internal/cmd/test/happy-path-validation-schema.zed b/internal/cmd/test/happy-path-validation-schema.zed new file mode 100644 index 0000000..053bff6 --- /dev/null +++ b/internal/cmd/test/happy-path-validation-schema.zed @@ -0,0 +1,6 @@ +definition user {} + +definition resource { + relation user: user + permission view = user +}