From ab498dc89a18aa74a440869c139bfc29fdf7cfbc Mon Sep 17 00:00:00 2001 From: oanatmaria Date: Thu, 19 Oct 2023 17:33:06 +0300 Subject: [PATCH] Add validation for Diff struct --- Depfile | 3 ++ cache/cache.go | 8 +++ go.mod | 21 ++++---- go.sum | 51 ++++++++----------- magefiles/magefile.go | 5 ++ model/diff/diff.go | 65 ++++++++++++++++++++++++ model/diff/diff_test.go | 69 ++++++++++++++++++++++++++ model/diff/mock_directory_validator.go | 64 ++++++++++++++++++++++++ model/model.go | 30 ++++------- model/model_test.go | 8 +-- 10 files changed, 261 insertions(+), 63 deletions(-) create mode 100644 model/diff/diff.go create mode 100644 model/diff/diff_test.go create mode 100644 model/diff/mock_directory_validator.go diff --git a/Depfile b/Depfile index 9114076..6cd685a 100644 --- a/Depfile +++ b/Depfile @@ -6,3 +6,6 @@ go: golangci-lint: importPath: "github.com/golangci/golangci-lint/cmd/golangci-lint" version: "v1.54.1" + mockgen: + importPath: github.com/golang/mock/mockgen + version: "v1.6.0" \ No newline at end of file diff --git a/cache/cache.go b/cache/cache.go index c3393ff..ade00dd 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -27,6 +27,14 @@ func (c *Cache) UpdateModel(m *model.Model) error { return nil } +// Returns a copy of the current model. +func (c *Cache) GetModel() model.Model { + c.mtx.Lock() + defer c.mtx.Unlock() + m := *c.model + return m +} + // ObjectExists, checks if given object type name exists in the model cache. func (c *Cache) ObjectExists(on model.ObjectName) bool { c.mtx.RLock() diff --git a/go.mod b/go.mod index df7a5b4..6ee4c89 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.19 require ( github.com/aserto-dev/errors v0.0.6 - github.com/aserto-dev/go-directory v0.21.7 + github.com/aserto-dev/go-directory v0.21.8-0.20230822195042-49f0ea959469 github.com/magefile/mage v1.15.0 github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 github.com/pkg/errors v0.9.1 github.com/samber/lo v1.38.1 github.com/stretchr/testify v1.8.4 - golang.org/x/text v0.12.0 - google.golang.org/grpc v1.57.0 + golang.org/x/text v0.13.0 + google.golang.org/grpc v1.58.3 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -19,15 +19,14 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/zerolog v1.30.0 // indirect - golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + github.com/rs/zerolog v1.31.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect ) diff --git a/go.sum b/go.sum index fac147c..0f641ee 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ github.com/aserto-dev/errors v0.0.6 h1:iH5fkJwBGFPbcdS4B8mwvNdwODlhDEXXPduZtjLh6vo= github.com/aserto-dev/errors v0.0.6/go.mod h1:kenI1gamsemaR2wS+M2un0kXIJ9exTrmeRT/fCFwlWc= -github.com/aserto-dev/go-directory v0.21.7 h1:eJXBz5zpOSmI99T+W0V4JufYeq87TbmiUtnHEYYi144= -github.com/aserto-dev/go-directory v0.21.7/go.mod h1:xzUJUiyOcVj9B8Nd/nNYsIB0JSQps3IMuiPKejZkCnc= -github.com/aserto-dev/go-directory v0.21.8-0.20230921154147-4f4347fa32c6 h1:oBWgBOa85P+WgjuteFt6U1KPrOeguWPyxDpHs09zHEc= -github.com/aserto-dev/go-directory v0.21.8-0.20230921154147-4f4347fa32c6/go.mod h1:ZsHSXALiP6F49/+zKDZP6GIcAWyYX95lkSVxM+8Jwno= +github.com/aserto-dev/go-directory v0.21.8-0.20230822195042-49f0ea959469 h1:KiDHP3XEn6b4oFmkknKrMM35cRbzrbyDj0vslfxb/u8= +github.com/aserto-dev/go-directory v0.21.8-0.20230822195042-49f0ea959469/go.mod h1:ZsHSXALiP6F49/+zKDZP6GIcAWyYX95lkSVxM+8Jwno= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -14,16 +12,14 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1 h1:LSsiG61v9IzzxMkqEr6nrix4miJI62xlRjwT7BYD2SM= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1/go.mod h1:Hbb13e3/WtqQ8U5hLGkek9gJvBLasHuPFI0UEGfnQ10= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -34,35 +30,32 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a h1:myvhA4is3vrit1a6NZCWBIwN0kNEnX21DJOJX/NvIfI= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/magefiles/magefile.go b/magefiles/magefile.go index df60869..6fdb5ea 100644 --- a/magefiles/magefile.go +++ b/magefiles/magefile.go @@ -28,3 +28,8 @@ func Test() error { func Deps() { deps.GetAllDeps() } + +// Generate generates all code. +func Generate() error { + return common.Generate() +} diff --git a/model/diff/diff.go b/model/diff/diff.go new file mode 100644 index 0000000..108d15b --- /dev/null +++ b/model/diff/diff.go @@ -0,0 +1,65 @@ +package diff + +import ( + "context" + + "github.com/aserto-dev/go-directory/pkg/derr" + "github.com/pkg/errors" +) + +//go:generate go run github.com/golang/mock/mockgen -destination=mock_directory_validator.go -package=diff github.com/aserto-dev/azm/model/diff DirectoryValidator + +type Diff struct { + Added Changes + Removed Changes +} + +type Changes struct { + Objects []string + Relations map[string][]string +} + +type DirectoryValidator interface { + HasObjectInstances(ctx context.Context, objectType string) (bool, error) + HasRelationInstances(ctx context.Context, objectType, relationName string) (bool, error) +} + +func (d *Diff) Validate(ctx context.Context, dv DirectoryValidator) error { + if err := d.validateObjectTypes(ctx, dv); err != nil { + return err + } + + if err := d.validateRelationsTypes(ctx, dv); err != nil { + return err + } + + return nil +} + +func (d *Diff) validateObjectTypes(ctx context.Context, dv DirectoryValidator) error { + for _, objType := range d.Removed.Objects { + hasInstance, err := dv.HasObjectInstances(ctx, objType) + if err != nil { + return err + } + if hasInstance { + return errors.Wrapf(derr.ErrObjectTypeInUse, "object type: %s", objType) + } + } + return nil +} + +func (d *Diff) validateRelationsTypes(ctx context.Context, dv DirectoryValidator) error { + for objType, rels := range d.Removed.Relations { + for _, rel := range rels { + hasInstance, err := dv.HasRelationInstances(ctx, objType, rel) + if err != nil { + return err + } + if hasInstance { + return errors.Wrapf(derr.ErrRelationTypeInUse, "relation type: %s; object type: %s", rel, objType) + } + } + } + return nil +} diff --git a/model/diff/diff_test.go b/model/diff/diff_test.go new file mode 100644 index 0000000..35f1d1d --- /dev/null +++ b/model/diff/diff_test.go @@ -0,0 +1,69 @@ +package diff_test + +import ( + "context" + "testing" + + "github.com/aserto-dev/azm/model/diff" + "github.com/aserto-dev/go-directory/pkg/derr" + gomock "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestValidateDiffNoDeletion(t *testing.T) { + ctrl := gomock.NewController(t) + mockDirectoryValidator := diff.NewMockDirectoryValidator(ctrl) + + dif := diff.Diff{Removed: diff.Changes{}, Added: diff.Changes{}} + err := dif.Validate(context.Background(), mockDirectoryValidator) + + require.NoError(t, err) +} + +func TestValidateDiffWithObjectTypeDeletion(t *testing.T) { + ctrl := gomock.NewController(t) + mockDirectoryValidator := diff.NewMockDirectoryValidator(ctrl) + objType := "user" + bCtx := context.Background() + + dif := diff.Diff{Removed: diff.Changes{Objects: []string{objType}}, Added: diff.Changes{}} + + mockDirectoryValidator.EXPECT().HasObjectInstances(bCtx, objType).Return(false, nil) + err := dif.Validate(bCtx, mockDirectoryValidator) + + require.NoError(t, err) +} + +func TestValidateDiffWith2ObjectTypeDeletion(t *testing.T) { + ctrl := gomock.NewController(t) + mockDirectoryValidator := diff.NewMockDirectoryValidator(ctrl) + objTypes := []string{"user", "member"} + bCtx := context.Background() + + dif := diff.Diff{Removed: diff.Changes{Objects: objTypes}, Added: diff.Changes{}} + + mockDirectoryValidator.EXPECT().HasObjectInstances(bCtx, objTypes[0]).Return(false, nil) + mockDirectoryValidator.EXPECT().HasObjectInstances(bCtx, objTypes[1]).Return(true, nil) + err := dif.Validate(bCtx, mockDirectoryValidator) + + require.Error(t, err) + require.Contains(t, err.Error(), derr.ErrObjectTypeInUse.Message) +} + +func TestValidateDiffWithRelationTypeDeletion(t *testing.T) { + ctrl := gomock.NewController(t) + mockDirectoryValidator := diff.NewMockDirectoryValidator(ctrl) + objTypes := []string{"user", "member"} + relationTypes := map[string][]string{"folder": {"parent_folder"}} + bCtx := context.Background() + + dif := diff.Diff{Removed: diff.Changes{Objects: objTypes, Relations: relationTypes}, Added: diff.Changes{}} + + mockDirectoryValidator.EXPECT().HasObjectInstances(bCtx, objTypes[0]).Return(false, nil) + mockDirectoryValidator.EXPECT().HasObjectInstances(bCtx, objTypes[1]).Return(false, nil) + mockDirectoryValidator.EXPECT().HasRelationInstances(bCtx, "folder", relationTypes["folder"][0]).Return(true, nil) + err := dif.Validate(bCtx, mockDirectoryValidator) + + require.Error(t, err) + require.Contains(t, err.Error(), derr.ErrRelationTypeInUse.Message) +} diff --git a/model/diff/mock_directory_validator.go b/model/diff/mock_directory_validator.go new file mode 100644 index 0000000..256c44d --- /dev/null +++ b/model/diff/mock_directory_validator.go @@ -0,0 +1,64 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/aserto-dev/azm/model/diff (interfaces: DirectoryValidator) + +// Package diff is a generated GoMock package. +package diff + +import ( + context "context" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockDirectoryValidator is a mock of DirectoryValidator interface +type MockDirectoryValidator struct { + ctrl *gomock.Controller + recorder *MockDirectoryValidatorMockRecorder +} + +// MockDirectoryValidatorMockRecorder is the mock recorder for MockDirectoryValidator +type MockDirectoryValidatorMockRecorder struct { + mock *MockDirectoryValidator +} + +// NewMockDirectoryValidator creates a new mock instance +func NewMockDirectoryValidator(ctrl *gomock.Controller) *MockDirectoryValidator { + mock := &MockDirectoryValidator{ctrl: ctrl} + mock.recorder = &MockDirectoryValidatorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockDirectoryValidator) EXPECT() *MockDirectoryValidatorMockRecorder { + return m.recorder +} + +// HasObjectInstances mocks base method +func (m *MockDirectoryValidator) HasObjectInstances(arg0 context.Context, arg1 string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasObjectInstances", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasObjectInstances indicates an expected call of HasObjectInstances +func (mr *MockDirectoryValidatorMockRecorder) HasObjectInstances(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasObjectInstances", reflect.TypeOf((*MockDirectoryValidator)(nil).HasObjectInstances), arg0, arg1) +} + +// HasRelationInstances mocks base method +func (m *MockDirectoryValidator) HasRelationInstances(arg0 context.Context, arg1, arg2 string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasRelationInstances", arg0, arg1, arg2) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasRelationInstances indicates an expected call of HasRelationInstances +func (mr *MockDirectoryValidatorMockRecorder) HasRelationInstances(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasRelationInstances", reflect.TypeOf((*MockDirectoryValidator)(nil).HasRelationInstances), arg0, arg1, arg2) +} diff --git a/model/model.go b/model/model.go index 6e0d6f3..33f9621 100644 --- a/model/model.go +++ b/model/model.go @@ -5,6 +5,8 @@ import ( "encoding/json" "io" "time" + + "github.com/aserto-dev/azm/model/diff" ) const ModelVersion int = 1 @@ -57,16 +59,6 @@ type Metadata struct { ETag string `json:"etag"` } -type Diff struct { - Added Changes - Removed Changes -} - -type Changes struct { - Objects []ObjectName - Relations map[ObjectName][]RelationName -} - func New(r io.Reader) (*Model, error) { m := Model{} dec := json.NewDecoder(r) @@ -91,19 +83,19 @@ func (m *Model) Write(w io.Writer) error { return enc.Encode(m) } -func (m *Model) Diff(newModel *Model) *Diff { +func (m *Model) Diff(newModel *Model) *diff.Diff { // newmodel - m => additions added := newModel.subtract(m) // m - newmodel => deletions deleted := m.subtract(newModel) - return &Diff{Added: *added, Removed: *deleted} + return &diff.Diff{Added: *added, Removed: *deleted} } -func (m *Model) subtract(newModel *Model) *Changes { - chgs := &Changes{ - Objects: make([]ObjectName, 0), - Relations: make(map[ObjectName][]RelationName), +func (m *Model) subtract(newModel *Model) *diff.Changes { + chgs := &diff.Changes{ + Objects: make([]string, 0), + Relations: make(map[string][]string), } if m == nil { @@ -112,18 +104,18 @@ func (m *Model) subtract(newModel *Model) *Changes { if newModel == nil { for objName := range m.Objects { - chgs.Objects = append(chgs.Objects, objName) + chgs.Objects = append(chgs.Objects, string(objName)) } return chgs } for objName, obj := range m.Objects { if newModel.Objects[objName] == nil { - chgs.Objects = append(chgs.Objects, objName) + chgs.Objects = append(chgs.Objects, string(objName)) } else { for relname := range obj.Relations { if newModel.Objects[objName].Relations[relname] == nil { - chgs.Relations[objName] = append(chgs.Relations[objName], relname) + chgs.Relations[string(objName)] = append(chgs.Relations[string(objName)], string(relname)) } } } diff --git a/model/model_test.go b/model/model_test.go index 61df45c..eecbf1e 100644 --- a/model/model_test.go +++ b/model/model_test.go @@ -217,12 +217,12 @@ func TestDiff(t *testing.T) { diffm1m3 := m1.Diff(&m3) require.Equal(t, len(diffm1m3.Added.Objects), 1) - require.Equal(t, diffm1m3.Added.Objects[0], model.ObjectName("new_user")) + require.Equal(t, diffm1m3.Added.Objects[0], "new_user") require.Equal(t, len(diffm1m3.Removed.Objects), 1) - require.Equal(t, diffm1m3.Removed.Objects[0], model.ObjectName("user")) + require.Equal(t, diffm1m3.Removed.Objects[0], "user") require.Equal(t, len(diffm1m3.Added.Relations), 1) - require.Equal(t, diffm1m3.Added.Relations["folder"], []model.RelationName{"viewer"}) + require.Equal(t, diffm1m3.Added.Relations["folder"], []string{"viewer"}) require.Equal(t, len(diffm1m3.Removed.Relations), 1) - require.Equal(t, diffm1m3.Removed.Relations["document"], []model.RelationName{"parent_folder"}) + require.Equal(t, diffm1m3.Removed.Relations["document"], []string{"parent_folder"}) }