mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 07:29:00 -08:00
276 lines
7.1 KiB
Go
276 lines
7.1 KiB
Go
package context
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zclconf/go-cty/cty"
|
|
"github.com/zclconf/go-cty/cty/gocty"
|
|
)
|
|
|
|
func Test_ContextVariables(t *testing.T) {
|
|
underlying := &hcl.EvalContext{}
|
|
ctx := NewContext(underlying, nil)
|
|
|
|
val, err := gocty.ToCtyValue("hello", cty.String)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ctx.Set(val, "my", "value")
|
|
value := underlying.Variables["my"].AsValueMap()["value"]
|
|
assert.Equal(t, "hello", value.AsString())
|
|
|
|
}
|
|
|
|
func Test_ContextVariablesPreservation(t *testing.T) {
|
|
|
|
underlying := &hcl.EvalContext{}
|
|
underlying.Variables = make(map[string]cty.Value)
|
|
underlying.Variables["x"], _ = gocty.ToCtyValue("does it work?", cty.String)
|
|
str, _ := gocty.ToCtyValue("something", cty.String)
|
|
underlying.Variables["my"] = cty.ObjectVal(map[string]cty.Value{
|
|
"other": str,
|
|
"obj": cty.ObjectVal(map[string]cty.Value{
|
|
"another": str,
|
|
}),
|
|
})
|
|
ctx := NewContext(underlying, nil)
|
|
|
|
val, err := gocty.ToCtyValue("hello", cty.String)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ctx.Set(val, "my", "value")
|
|
assert.Equal(t, "hello", underlying.Variables["my"].AsValueMap()["value"].AsString())
|
|
assert.Equal(t, "something", underlying.Variables["my"].AsValueMap()["other"].AsString())
|
|
assert.Equal(t, "something", underlying.Variables["my"].AsValueMap()["obj"].AsValueMap()["another"].AsString())
|
|
assert.Equal(t, "does it work?", underlying.Variables["x"].AsString())
|
|
|
|
}
|
|
|
|
func Test_SetWithMerge(t *testing.T) {
|
|
hctx := hcl.EvalContext{
|
|
Variables: map[string]cty.Value{
|
|
"my": cty.ObjectVal(map[string]cty.Value{
|
|
"someValue": cty.ObjectVal(map[string]cty.Value{
|
|
"foo": cty.StringVal("test"),
|
|
"bar": cty.ObjectVal(map[string]cty.Value{
|
|
"foo": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
}),
|
|
},
|
|
}
|
|
|
|
ctx := NewContext(&hctx, nil)
|
|
|
|
val := cty.ObjectVal(map[string]cty.Value{
|
|
"foo2": cty.StringVal("test2"),
|
|
"bar": cty.ObjectVal(map[string]cty.Value{
|
|
"foo2": cty.StringVal("test2"),
|
|
}),
|
|
})
|
|
|
|
ctx.Set(val, "my", "someValue")
|
|
got := ctx.Get("my", "someValue")
|
|
expected := cty.ObjectVal(map[string]cty.Value{
|
|
"foo": cty.StringVal("test"),
|
|
"foo2": cty.StringVal("test2"),
|
|
"bar": cty.ObjectVal(map[string]cty.Value{
|
|
"foo": cty.StringVal("test"),
|
|
"foo2": cty.StringVal("test2"),
|
|
}),
|
|
})
|
|
|
|
assert.Equal(t, expected, got)
|
|
}
|
|
|
|
func Test_ContextVariablesPreservationByDot(t *testing.T) {
|
|
|
|
underlying := &hcl.EvalContext{}
|
|
underlying.Variables = make(map[string]cty.Value)
|
|
underlying.Variables["x"], _ = gocty.ToCtyValue("does it work?", cty.String)
|
|
str, _ := gocty.ToCtyValue("something", cty.String)
|
|
underlying.Variables["my"] = cty.ObjectVal(map[string]cty.Value{
|
|
"other": str,
|
|
"obj": cty.ObjectVal(map[string]cty.Value{
|
|
"another": str,
|
|
}),
|
|
})
|
|
ctx := NewContext(underlying, nil)
|
|
|
|
val, err := gocty.ToCtyValue("hello", cty.String)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ctx.SetByDot(val, "my.something.value")
|
|
assert.Equal(t, "hello", underlying.Variables["my"].AsValueMap()["something"].AsValueMap()["value"].AsString())
|
|
assert.Equal(t, "something", underlying.Variables["my"].AsValueMap()["other"].AsString())
|
|
assert.Equal(t, "something", underlying.Variables["my"].AsValueMap()["obj"].AsValueMap()["another"].AsString())
|
|
assert.Equal(t, "does it work?", underlying.Variables["x"].AsString())
|
|
}
|
|
|
|
func Test_ContextSetThenImmediateGet(t *testing.T) {
|
|
|
|
underlying := &hcl.EvalContext{}
|
|
|
|
ctx := NewContext(underlying, nil)
|
|
|
|
ctx.Set(cty.ObjectVal(map[string]cty.Value{
|
|
"mod_result": cty.StringVal("ok"),
|
|
}), "module", "modulename")
|
|
|
|
val := ctx.Get("module", "modulename", "mod_result")
|
|
assert.Equal(t, "ok", val.AsString())
|
|
}
|
|
|
|
func Test_ContextSetThenImmediateGetWithChild(t *testing.T) {
|
|
|
|
underlying := &hcl.EvalContext{}
|
|
|
|
ctx := NewContext(underlying, nil)
|
|
|
|
childCtx := ctx.NewChild()
|
|
|
|
childCtx.Root().Set(cty.ObjectVal(map[string]cty.Value{
|
|
"mod_result": cty.StringVal("ok"),
|
|
}), "module", "modulename")
|
|
|
|
val := ctx.Get("module", "modulename", "mod_result")
|
|
assert.Equal(t, "ok", val.AsString())
|
|
}
|
|
|
|
func Test_MergeObjects(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
name string
|
|
oldVal cty.Value
|
|
newVal cty.Value
|
|
expected cty.Value
|
|
}{
|
|
{
|
|
name: "happy",
|
|
oldVal: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("some_id"),
|
|
"arn": cty.StringVal("some_arn"),
|
|
}),
|
|
}),
|
|
newVal: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"arn": cty.StringVal("some_new_arn"),
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
expected: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("some_id"),
|
|
"arn": cty.StringVal("some_new_arn"),
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
},
|
|
{
|
|
name: "old value is empty",
|
|
oldVal: cty.EmptyObjectVal,
|
|
newVal: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
expected: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
},
|
|
{
|
|
name: "new value is empty",
|
|
oldVal: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
newVal: cty.EmptyObjectVal,
|
|
expected: cty.ObjectVal(map[string]cty.Value{
|
|
"this": cty.ObjectVal(map[string]cty.Value{
|
|
"bucket": cty.StringVal("test"),
|
|
}),
|
|
}),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.expected, mergeObjects(tt.oldVal, tt.newVal))
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func Test_IsNotEmptyObject(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
val cty.Value
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "happy",
|
|
val: cty.ObjectVal(map[string]cty.Value{
|
|
"field": cty.NilVal,
|
|
}),
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "empty object",
|
|
val: cty.EmptyObjectVal,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "nil value",
|
|
val: cty.NilVal,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "dynamic value",
|
|
val: cty.DynamicVal,
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.expected, isNotEmptyObject(tt.val))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReplace(t *testing.T) {
|
|
t.Run("replacement of an existing value", func(t *testing.T) {
|
|
underlying := &hcl.EvalContext{}
|
|
ctx := NewContext(underlying, nil)
|
|
ctx.SetByDot(cty.StringVal("some-value"), "my.value")
|
|
require.NotEqual(t, cty.NilVal, ctx.GetByDot("my.value"))
|
|
ctx.Replace(cty.NumberIntVal(-1), "my.value")
|
|
assert.Equal(t, cty.NumberIntVal(-1), ctx.GetByDot("my.value"))
|
|
})
|
|
|
|
t.Run("replacement of a non-existing value", func(t *testing.T) {
|
|
underlying := &hcl.EvalContext{}
|
|
ctx := NewContext(underlying, nil)
|
|
ctx.Replace(cty.NumberIntVal(-1), "my.value")
|
|
assert.Equal(t, cty.NumberIntVal(-1), ctx.GetByDot("my.value"))
|
|
})
|
|
|
|
t.Run("empty path", func(t *testing.T) {
|
|
underlying := &hcl.EvalContext{}
|
|
ctx := NewContext(underlying, nil)
|
|
ctx.Replace(cty.NumberIntVal(-1), "")
|
|
})
|
|
}
|