Skip to content

Commit

Permalink
feat: undefined detection
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasjarosch committed Mar 11, 2024
1 parent e80ce28 commit 66b1087
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 12 deletions.
31 changes: 23 additions & 8 deletions inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package skipper

import (
"fmt"

"github.com/davecgh/go-spew/spew"
"strings"

"github.com/lukasjarosch/skipper/data"
)
Expand All @@ -14,14 +13,20 @@ type Scope string
var (
DataScope Scope = "data"
TargetsScope Scope = "targets"

// UndefinedValue is a value which must be defined during compilation
// To ensure all values which can only be set within the target are actually set,
// one can use this value.
UndefinedValue = data.NewValue("__undefined__")
)

var (
ErrEmptyScope = fmt.Errorf("scope is empty")
ErrNilRegistry = fmt.Errorf("registry is nil")
ErrScopeDoesNotExist = fmt.Errorf("scope does not exist")
ErrScopeAlreadyRegistered = fmt.Errorf("scope already registered")
ErrTargetCannotIntroducePaths = fmt.Errorf("target cannot introduce new paths")
ErrEmptyScope = fmt.Errorf("scope is empty")
ErrNilRegistry = fmt.Errorf("registry is nil")
ErrScopeDoesNotExist = fmt.Errorf("scope does not exist")
ErrScopeAlreadyRegistered = fmt.Errorf("scope already registered")
ErrTargetCannotIntroducePaths = fmt.Errorf("target cannot introduce new paths")
ErrUndefinedValueNotOverwritten = fmt.Errorf("undefined value was not overwritten by target")
)

// Inventory is the top-level abstraction which represents all data.
Expand Down Expand Up @@ -122,7 +127,6 @@ func (inv *Inventory) Compile(target data.Path) error {
}

// The path exists within the inventory, overwrite it with the value from the target.
spew.Println("OVERWRITTEN", pathWithoutClassName)
err = inv.SetPath(pathWithoutClassName, v.Raw)
if err != nil {
return fmt.Errorf("failed to overwrite path %s: %w", pathWithoutClassName, err)
Expand All @@ -133,6 +137,17 @@ func (inv *Inventory) Compile(target data.Path) error {
return err
}

// undefined value detection, go through all paths to ensure all values are no 'UndefinedValue'
err = inv.WalkValues(func(p data.Path, v data.Value) error {
if strings.ToLower(strings.TrimSpace(v.String())) == UndefinedValue.String() {
return fmt.Errorf("%w: %s", ErrUndefinedValueNotOverwritten, p)
}
return nil
})
if err != nil {
return err
}

return nil
}

Expand Down
34 changes: 30 additions & 4 deletions inventory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ func TestInventoryAbsolutePath(t *testing.T) {
}

func TestInventory_Compile(t *testing.T) {
dataRegistry := func() *Registry {
commonClass, err := NewClass("testdata/compile/data/common.yaml", codec.NewYamlCodec(), data.NewPath("common"))
dataRegistry := func(class string) *Registry {
commonClass, err := NewClass(fmt.Sprintf("testdata/compile/data/%s.yaml", class), codec.NewYamlCodec(), data.NewPath(class))
assert.NoError(t, err)
dataRegistry := NewRegistry()
err = dataRegistry.RegisterClass(commonClass)
Expand All @@ -182,7 +182,7 @@ func TestInventory_Compile(t *testing.T) {

t.Run("valid target", func(t *testing.T) {
inventory, _ := NewInventory()
err := inventory.RegisterScope(DataScope, dataRegistry())
err := inventory.RegisterScope(DataScope, dataRegistry("common"))
assert.NoError(t, err)
err = inventory.RegisterScope(TargetsScope, targetRegistry("valid"))
assert.NoError(t, err)
Expand All @@ -204,12 +204,38 @@ func TestInventory_Compile(t *testing.T) {

t.Run("target cannot introduce paths in the inventory", func(t *testing.T) {
inventory, _ := NewInventory()
err := inventory.RegisterScope(DataScope, dataRegistry())
err := inventory.RegisterScope(DataScope, dataRegistry("common"))
assert.NoError(t, err)
err = inventory.RegisterScope(TargetsScope, targetRegistry("introduce_paths"))
assert.NoError(t, err)

err = inventory.Compile(data.NewPath("targets.introduce_paths"))
assert.ErrorIs(t, err, ErrTargetCannotIntroducePaths)
})

t.Run("error if undefined value is not overwritten", func(t *testing.T) {
inventory, _ := NewInventory()
err := inventory.RegisterScope(DataScope, dataRegistry("undefined"))
assert.NoError(t, err)
err = inventory.RegisterScope(TargetsScope, targetRegistry("not_overwritten_undefined"))
assert.NoError(t, err)

err = inventory.Compile(data.NewPath("targets.not_overwritten_undefined"))
assert.ErrorIs(t, err, ErrUndefinedValueNotOverwritten)
})

t.Run("no error if undefined value is overwritten", func(t *testing.T) {
inventory, _ := NewInventory()
err := inventory.RegisterScope(DataScope, dataRegistry("undefined"))
assert.NoError(t, err)
err = inventory.RegisterScope(TargetsScope, targetRegistry("overwritten_undefined"))
assert.NoError(t, err)

err = inventory.Compile(data.NewPath("targets.overwritten_undefined"))
assert.NoError(t, err)

val, err := inventory.Get("data.undefined.network_cidr")
assert.NoError(t, err)
assert.Equal(t, "10.0.0.0/8", val.String())
})
}
2 changes: 2 additions & 0 deletions testdata/compile/data/undefined.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
undefined:
network_cidr: __undefined__
2 changes: 2 additions & 0 deletions testdata/compile/targets/not_overwritten_undefined.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
not_overwritten_undefined:
lol: nothing
2 changes: 2 additions & 0 deletions testdata/compile/targets/overwritten_undefined.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
overwritten_undefined:
data.undefined.network_cidr: 10.0.0.0/8

0 comments on commit 66b1087

Please sign in to comment.