You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform/internal/configs/action_test.go

226 lines
6.7 KiB

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package configs
import (
"testing"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hcltest"
"github.com/zclconf/go-cty/cty"
)
func TestDecodeActionBlock(t *testing.T) {
tests := map[string]struct {
input *hcl.Block
want *Action
expectDiags []string
}{
"valid": {
&hcl.Block{
Type: "action",
Labels: []string{"an_action", "foo"},
Body: hcl.EmptyBody(),
DefRange: blockRange,
LabelRanges: []hcl.Range{{}},
},
&Action{
Type: "an_action",
Name: "foo",
DeclRange: blockRange,
},
nil,
},
"count and for_each conflict": {
&hcl.Block{
Type: "action",
Labels: []string{"an_action", "foo"},
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"count": hcltest.MockExprLiteral(cty.NumberIntVal(2)),
"for_each": hcltest.MockExprLiteral(cty.StringVal("something")),
}),
}),
DefRange: blockRange,
LabelRanges: []hcl.Range{{}},
},
&Action{
Type: "an_action",
Name: "foo",
DeclRange: blockRange,
Count: hcltest.MockExprLiteral(cty.NumberIntVal(2)),
ForEach: hcltest.MockExprLiteral(cty.StringVal("something")),
},
[]string{"MockAttrs:0,0-0: Invalid combination of \"count\" and \"for_each\"; The \"count\" and \"for_each\" meta-arguments are mutually-exclusive, only one should be used."},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
got, diags := decodeActionBlock(test.input)
assertExactDiagnostics(t, diags, test.expectDiags)
assertResultDeepEqual(t, got, test.want)
})
}
}
func TestDecodeActionTriggerBlock(t *testing.T) {
conditionExpr := hcltest.MockExprLiteral(cty.True)
eventsListExpr := hcltest.MockExprList([]hcl.Expression{hcltest.MockExprTraversalSrc("after_create"), hcltest.MockExprTraversalSrc("after_update")})
fooActionExpr := hcltest.MockExprTraversalSrc("action.action_type.foo")
barActionExpr := hcltest.MockExprTraversalSrc("action.action_type.bar")
fooAndBarExpr := hcltest.MockExprList([]hcl.Expression{fooActionExpr, barActionExpr})
// bad inputs!
moduleActionExpr := hcltest.MockExprTraversalSrc("module.foo.action.action_type.bar")
fooDataSourceExpr := hcltest.MockExprTraversalSrc("data.example.foo")
tests := map[string]struct {
input *hcl.Block
want *ActionTrigger
expectDiags []string
}{
"simple example": {
&hcl.Block{
Type: "action_trigger",
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"condition": conditionExpr,
"events": eventsListExpr,
"actions": fooAndBarExpr,
}),
}),
},
&ActionTrigger{
Condition: conditionExpr,
Events: []ActionTriggerEvent{AfterCreate, AfterUpdate},
Actions: []ActionRef{
{
fooActionExpr,
fooActionExpr.Range(),
},
{
barActionExpr,
barActionExpr.Range(),
},
},
},
nil,
},
"error - referencing actions in other modules": {
&hcl.Block{
Type: "action_trigger",
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"condition": conditionExpr,
"events": eventsListExpr,
"actions": hcltest.MockExprList([]hcl.Expression{moduleActionExpr}),
}),
}),
},
&ActionTrigger{
Condition: conditionExpr,
Events: []ActionTriggerEvent{AfterCreate, AfterUpdate},
Actions: []ActionRef{
{
Expr: moduleActionExpr,
Range: moduleActionExpr.Range(),
},
},
},
[]string{
"MockExprTraversal:0,0-33: No actions specified; At least one action must be specified for an action_trigger.",
"MockExprTraversal:0,0-33: Invalid reference to action outside this module; Actions can only be referenced in the module they are declared in.",
},
},
"error - action is not an action": {
&hcl.Block{
Type: "action_trigger",
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"condition": conditionExpr,
"events": eventsListExpr,
"actions": hcltest.MockExprList([]hcl.Expression{fooDataSourceExpr}),
}),
}),
},
&ActionTrigger{
Condition: conditionExpr,
Events: []ActionTriggerEvent{AfterCreate, AfterUpdate},
Actions: []ActionRef{
{
Expr: fooDataSourceExpr,
Range: fooDataSourceExpr.Range(),
},
},
},
[]string{
"MockExprTraversal:0,0-16: No actions specified; At least one action must be specified for an action_trigger.",
"MockExprTraversal:0,0-16: Invalid action argument inside action_triggers; action_triggers.actions must only refer to actions in the current module.",
},
},
"error - invalid event": {
&hcl.Block{
Type: "action_trigger",
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"condition": conditionExpr,
"events": hcltest.MockExprList([]hcl.Expression{hcltest.MockExprTraversalSrc("not_an_event")}),
"actions": hcltest.MockExprList([]hcl.Expression{fooActionExpr}),
}),
}),
},
&ActionTrigger{
Condition: conditionExpr,
Events: []ActionTriggerEvent{},
Actions: []ActionRef{
{
fooActionExpr,
fooActionExpr.Range(),
},
},
},
[]string{
"MockExprTraversal:0,0-12: Invalid \"event\" value not_an_event; The \"event\" argument supports the following values: before_create, after_create, before_update, after_update.",
":0,0-0: No events specified; At least one event must be specified for an action_trigger.",
},
},
"error - duplicate event": {
&hcl.Block{
Type: "action_trigger",
Body: hcltest.MockBody(&hcl.BodyContent{
Attributes: hcltest.MockAttrs(map[string]hcl.Expression{
"condition": conditionExpr,
"events": hcltest.MockExprList([]hcl.Expression{hcltest.MockExprTraversalSrc("before_create"), hcltest.MockExprTraversalSrc("before_create")}),
"actions": hcltest.MockExprList([]hcl.Expression{fooActionExpr}),
}),
}),
},
&ActionTrigger{
Condition: conditionExpr,
Events: []ActionTriggerEvent{BeforeCreate},
Actions: []ActionRef{
{
fooActionExpr,
fooActionExpr.Range(),
},
},
},
[]string{
`MockExprTraversal:0,0-13: Duplicate "before_create" event; The event is already defined in this action_trigger block.`,
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
got, diags := decodeActionTriggerBlock(test.input)
assertExactDiagnostics(t, diags, test.expectDiags)
assertResultDeepEqual(t, got, test.want)
})
}
}