From 6aa063aeee03f08327afe162bfece2dcb51d0438 Mon Sep 17 00:00:00 2001 From: rafiramadhana Date: Thu, 21 Sep 2023 00:02:09 +0700 Subject: [PATCH 1/2] Add validation Add layer dependencies validation. --- internal/layerfile/layerfile.go | 27 +++++++++++++++- internal/layerfile/layerfile_test.go | 46 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/internal/layerfile/layerfile.go b/internal/layerfile/layerfile.go index 4fbbc82..d5c22b5 100644 --- a/internal/layerfile/layerfile.go +++ b/internal/layerfile/layerfile.go @@ -12,7 +12,10 @@ import ( "github.com/ergomake/layerform/pkg/data" ) -var ErrInvalidDefinitionName = errors.New("invalid layer definition name") +var ( + ErrInvalidDefinitionName = errors.New("invalid layer definition name") + ErrDependencyDoesNotExist = errors.New("dependency does not exist") +) var alphanumericRegex = regexp.MustCompile("^[A-Za-z0-9][A-Za-z0-9_-]*[A-Za-z0-9]$") @@ -40,6 +43,10 @@ func FromFile(sourceFilepath string) (*layerfile, error) { } func (lf *layerfile) ToLayers() ([]*data.LayerDefinition, error) { + if err := lf.validateLayersDependencies(); err != nil { + return nil, errors.Wrap(err, "fail to validate layers dependencies") + } + dir := path.Dir(lf.sourceFilepath) dataLayers := make([]*data.LayerDefinition, len(lf.Layers)) @@ -89,3 +96,21 @@ func (lf *layerfile) ToLayers() ([]*data.LayerDefinition, error) { return dataLayers, nil } + +func (lf *layerfile) validateLayersDependencies() error { + names := make(map[string]struct{}) + + for _, l := range lf.Layers { + names[l.Name] = struct{}{} + } + + for _, l := range lf.Layers { + for _, d := range l.Dependencies { + if _, ok := names[d]; !ok { + return errors.Wrap(ErrDependencyDoesNotExist, d) + } + } + } + + return nil +} diff --git a/internal/layerfile/layerfile_test.go b/internal/layerfile/layerfile_test.go index 0ddc43c..f08fbb7 100644 --- a/internal/layerfile/layerfile_test.go +++ b/internal/layerfile/layerfile_test.go @@ -135,3 +135,49 @@ func TestToLayers_ValidateNameOfLayerDefinitions(t *testing.T) { }) } } + +func TestToLayers_ValidateAllDependenciesExist(t *testing.T) { + tests := []struct { + name string + lf layerfile + err error + }{ + { + name: "Dependencies don't exist", + lf: layerfile{ + Layers: []layerfileLayer{ + { + Name: "foo", + Dependencies: []string{"bar"}, + }, + }, + }, + err: ErrDependencyDoesNotExist, + }, + { + name: "Dependencies exist", + lf: layerfile{ + Layers: []layerfileLayer{ + { + Name: "foo", + Dependencies: []string{"bar"}, + }, + { + Name: "bar", + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := tt.lf.ToLayers() + if tt.err == nil { + assert.NoError(t, err) + } else { + assert.ErrorIs(t, err, tt.err) + } + }) + } +} From d0274ae695c47ccdf7a42c0dccf3ac334c3c6dc5 Mon Sep 17 00:00:00 2001 From: rafiramadhana Date: Thu, 21 Sep 2023 09:08:17 +0700 Subject: [PATCH 2/2] Update unit test Add more test cases. --- internal/layerfile/layerfile_test.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/layerfile/layerfile_test.go b/internal/layerfile/layerfile_test.go index f08fbb7..593ea55 100644 --- a/internal/layerfile/layerfile_test.go +++ b/internal/layerfile/layerfile_test.go @@ -148,7 +148,10 @@ func TestToLayers_ValidateAllDependenciesExist(t *testing.T) { Layers: []layerfileLayer{ { Name: "foo", - Dependencies: []string{"bar"}, + Dependencies: []string{"bar", "baz"}, + }, + { + Name: "bar", }, }, }, @@ -168,6 +171,25 @@ func TestToLayers_ValidateAllDependenciesExist(t *testing.T) { }, }, }, + { + name: "Layers have no dependencies", + lf: layerfile{ + Layers: []layerfileLayer{ + { + Name: "foo", + }, + { + Name: "bar", + }, + }, + }, + }, + { + name: "No layers", + lf: layerfile{ + Layers: []layerfileLayer{}, + }, + }, } for _, tt := range tests {