mirror of
https://github.com/turbot/steampipe.git
synced 2026-05-11 00:02:37 -04:00
Only top level resources can have with and param blocks. Closes #2872 Refactor resource and dashboard run hierarchies to use base impl structs. Closes #2873
352 lines
9.0 KiB
Go
352 lines
9.0 KiB
Go
package modconfig
|
|
|
|
import (
|
|
"github.com/turbot/go-kit/helpers"
|
|
"github.com/turbot/steampipe/pkg/utils"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
type resolveParamsTest struct {
|
|
baseArgs *QueryArgs
|
|
runtimeArgs *QueryArgs
|
|
paramDefs []*ParamDef
|
|
expected interface{}
|
|
}
|
|
|
|
// NOTE: all QueryArgs values are Json representations of the arg value
|
|
// TODO really we should update the trest to set stringNamedArgs and stringPositionalArgs for each args object
|
|
// then we can store the string args as normal strings, not json strings
|
|
// TODO add other args types - arrays, json etc.
|
|
|
|
var testCasesResolveParams = map[string]resolveParamsTest{
|
|
|
|
"named argsno defs": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
paramDefs: nil,
|
|
expected: []any(nil),
|
|
},
|
|
"named args with defs": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: []any{"val1", "val2"},
|
|
},
|
|
"named args with defs and partial runtime overrides": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p2": `"runtime val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: []any{"val1", "runtime val2"},
|
|
},
|
|
|
|
"named args with defs and full runtime overrides": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"runtime val1"`,
|
|
"p2": `"runtime val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: []any{"runtime val1", "runtime val2"},
|
|
},
|
|
"named args with defs and runtime overrides with additional undefined arg": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p2": `"runtime val2"`,
|
|
"p3": `"runtime val3"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: []any{"val1", "runtime val2"},
|
|
},
|
|
|
|
"named arg overrides only with defs": {
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"override val1"`,
|
|
"p2": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: []any{"override val1", "override val2"},
|
|
},
|
|
"named param defs with incomplete overrides": {
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p2": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: "ERROR",
|
|
},
|
|
"named param defs with incomplete invalid overrides": {
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p3": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1"},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: "ERROR",
|
|
},
|
|
"named param defs with defaults with incomplete overrides": {
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p2": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
expected: []any{"val1", "override val2"},
|
|
},
|
|
"named param defs with defaults with undefined override": {
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p3": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
expected: []any{"val1", "val2"},
|
|
},
|
|
|
|
"partial named args with defs and defaults": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"def_val2"`)},
|
|
},
|
|
expected: []any{"val1", "def_val2"},
|
|
},
|
|
"partial named args with defs defaults and partial override": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p2": `"override val2"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"def_val2"`)},
|
|
{ShortName: "p3", Default: utils.ToStringPointer(`"def_val3"`)},
|
|
},
|
|
|
|
expected: []any{"val1", "override val2", "def_val3"},
|
|
},
|
|
"partial named args with defs and unmatched defaults": {
|
|
// only a default for first param, which is populated from the provided positional param
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: "ERROR",
|
|
},
|
|
|
|
"positional params no defs": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
paramDefs: nil,
|
|
|
|
expected: []any{"val1", "val2"},
|
|
},
|
|
"positional params with partial runtime override no defs": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgList: []*string{nil, utils.ToStringPointer(`"override val2"`)},
|
|
},
|
|
paramDefs: nil,
|
|
expected: []any{"val1", "override val2"},
|
|
},
|
|
"positional params with full runtime override no defs": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"override val1"`), utils.ToStringPointer(`"override val2"`)},
|
|
},
|
|
paramDefs: nil,
|
|
expected: []any{"override val1", "override val2"},
|
|
},
|
|
"partial positional args with defs and defaults": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`)},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"def_val2"`)},
|
|
},
|
|
expected: []any{"val1", "def_val2"},
|
|
},
|
|
"partial positional args with defs, overrides and defaults": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`)},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgList: []*string{nil, utils.ToStringPointer(`"override val2"`)},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2", Default: utils.ToStringPointer(`"def_val2"`)},
|
|
{ShortName: "p3", Default: utils.ToStringPointer(`"def_val3"`)},
|
|
},
|
|
expected: []any{"val1", "override val2", "def_val3"},
|
|
},
|
|
"partial positional args with defs and unmatched defaults": {
|
|
// only a default for first param, which is populated from the provided positional param
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`)},
|
|
},
|
|
paramDefs: []*ParamDef{
|
|
{ShortName: "p1", Default: utils.ToStringPointer(`"def_val1"`)},
|
|
{ShortName: "p2"},
|
|
},
|
|
expected: "ERROR",
|
|
},
|
|
|
|
"positional and named args(expect error)": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
paramDefs: nil,
|
|
expected: "ERROR",
|
|
},
|
|
"positional and override named args (expect error)": {
|
|
baseArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
paramDefs: nil,
|
|
expected: "ERROR",
|
|
},
|
|
"named and override params (expect error)": {
|
|
baseArgs: &QueryArgs{
|
|
ArgMap: map[string]string{
|
|
"p1": `"val1"`,
|
|
"p2": `"val2"`,
|
|
},
|
|
},
|
|
runtimeArgs: &QueryArgs{
|
|
ArgList: []*string{utils.ToStringPointer(`"val1"`), utils.ToStringPointer(`"val2"`)},
|
|
},
|
|
paramDefs: nil,
|
|
expected: "ERROR",
|
|
},
|
|
}
|
|
|
|
func TestResolveAsString(t *testing.T) {
|
|
testsToRun := []string{}
|
|
|
|
for name, test := range testCasesResolveParams {
|
|
if len(testsToRun) > 0 && !helpers.StringSliceContains(testsToRun, name) {
|
|
continue
|
|
}
|
|
query := &Control{
|
|
QueryProviderImpl: QueryProviderImpl{
|
|
RuntimeDependencyProviderImpl: RuntimeDependencyProviderImpl{
|
|
ModTreeItemImpl: ModTreeItemImpl{
|
|
HclResourceImpl: HclResourceImpl{
|
|
FullName: "control.test_control",
|
|
},
|
|
},
|
|
},
|
|
Params: test.paramDefs,
|
|
Args: test.baseArgs,
|
|
},
|
|
}
|
|
res, err := ResolveArgs(query, test.runtimeArgs)
|
|
if err != nil {
|
|
if test.expected != "ERROR" {
|
|
t.Errorf("Test: '%s'' FAILED : \nunexpected error %v", name, err)
|
|
}
|
|
continue
|
|
}
|
|
if test.expected == "ERROR" {
|
|
t.Errorf("Test: '%s'' FAILED - expected error", name)
|
|
continue
|
|
}
|
|
expected := test.expected.([]any)
|
|
if !reflect.DeepEqual(expected, res) {
|
|
t.Errorf("Test: '%s'' FAILED : \nexpected:\n %v, \ngot:\n %v\n", name, test.expected, res)
|
|
}
|
|
}
|
|
}
|