2021-02-23 16:16:09 +01:00
|
|
|
package json
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
2021-07-30 19:37:23 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
2021-06-24 23:53:43 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
2021-07-30 19:37:23 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/plans"
|
2021-05-17 21:43:35 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/states"
|
2021-02-23 16:16:09 +01:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestOutputsFromMap(t *testing.T) {
|
|
|
|
got, diags := OutputsFromMap(map[string]*states.OutputValue{
|
|
|
|
// Normal non-sensitive output
|
|
|
|
"boop": {
|
|
|
|
Value: cty.NumberIntVal(1234),
|
|
|
|
},
|
|
|
|
// Sensitive string output
|
|
|
|
"beep": {
|
2021-06-24 23:53:43 +02:00
|
|
|
Value: cty.StringVal("horse-battery").Mark(marks.Sensitive),
|
2021-02-23 16:16:09 +01:00
|
|
|
Sensitive: true,
|
|
|
|
},
|
|
|
|
// Sensitive object output which is marked at the leaf
|
|
|
|
"blorp": {
|
|
|
|
Value: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
2021-06-24 23:53:43 +02:00
|
|
|
"c": cty.StringVal("oh, hi").Mark(marks.Sensitive),
|
2021-02-23 16:16:09 +01:00
|
|
|
}),
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
Sensitive: true,
|
|
|
|
},
|
|
|
|
// Null value
|
|
|
|
"honk": {
|
|
|
|
Value: cty.NullVal(cty.Map(cty.Bool)),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if len(diags) > 0 {
|
|
|
|
t.Fatal(diags.Err())
|
|
|
|
}
|
|
|
|
|
|
|
|
want := Outputs{
|
|
|
|
"boop": {
|
|
|
|
Sensitive: false,
|
|
|
|
Type: json.RawMessage(`"number"`),
|
|
|
|
Value: json.RawMessage(`1234`),
|
|
|
|
},
|
|
|
|
"beep": {
|
|
|
|
Sensitive: true,
|
|
|
|
Type: json.RawMessage(`"string"`),
|
|
|
|
Value: json.RawMessage(`"horse-battery"`),
|
|
|
|
},
|
|
|
|
"blorp": {
|
|
|
|
Sensitive: true,
|
|
|
|
Type: json.RawMessage(`["object",{"a":["object",{"b":["object",{"c":"string"}]}]}]`),
|
|
|
|
Value: json.RawMessage(`{"a":{"b":{"c":"oh, hi"}}}`),
|
|
|
|
},
|
|
|
|
"honk": {
|
|
|
|
Sensitive: false,
|
|
|
|
Type: json.RawMessage(`["map","bool"]`),
|
|
|
|
Value: json.RawMessage(`null`),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !cmp.Equal(want, got) {
|
|
|
|
t.Fatalf("unexpected result\n%s", cmp.Diff(want, got))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-30 19:37:23 +02:00
|
|
|
func TestOutputsFromChanges(t *testing.T) {
|
|
|
|
root := addrs.RootModuleInstance
|
|
|
|
num, err := plans.NewDynamicValue(cty.NumberIntVal(1234), cty.Number)
|
2021-08-31 23:33:26 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error creating dynamic value: %v", err)
|
|
|
|
}
|
2021-07-30 19:37:23 +02:00
|
|
|
str, err := plans.NewDynamicValue(cty.StringVal("1234"), cty.String)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error creating dynamic value: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
got := OutputsFromChanges([]*plans.OutputChangeSrc{
|
|
|
|
// Unchanged output "boop", value 1234
|
|
|
|
{
|
|
|
|
Addr: root.OutputValue("boop"),
|
|
|
|
ChangeSrc: plans.ChangeSrc{
|
|
|
|
Action: plans.NoOp,
|
|
|
|
Before: num,
|
|
|
|
After: num,
|
|
|
|
},
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
// New output "beep", value 1234
|
|
|
|
{
|
|
|
|
Addr: root.OutputValue("beep"),
|
|
|
|
ChangeSrc: plans.ChangeSrc{
|
|
|
|
Action: plans.Create,
|
|
|
|
Before: nil,
|
|
|
|
After: num,
|
|
|
|
},
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
// Deleted output "blorp", prior value 1234
|
|
|
|
{
|
|
|
|
Addr: root.OutputValue("blorp"),
|
|
|
|
ChangeSrc: plans.ChangeSrc{
|
|
|
|
Action: plans.Delete,
|
|
|
|
Before: num,
|
|
|
|
After: nil,
|
|
|
|
},
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
// Updated output "honk", prior value 1234, new value "1234"
|
|
|
|
{
|
|
|
|
Addr: root.OutputValue("honk"),
|
|
|
|
ChangeSrc: plans.ChangeSrc{
|
|
|
|
Action: plans.Update,
|
|
|
|
Before: num,
|
|
|
|
After: str,
|
|
|
|
},
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
// New sensitive output "secret", value "1234"
|
|
|
|
{
|
|
|
|
Addr: root.OutputValue("secret"),
|
|
|
|
ChangeSrc: plans.ChangeSrc{
|
|
|
|
Action: plans.Create,
|
|
|
|
Before: nil,
|
|
|
|
After: str,
|
|
|
|
},
|
|
|
|
Sensitive: true,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
want := Outputs{
|
|
|
|
"boop": {
|
|
|
|
Action: "noop",
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
"beep": {
|
|
|
|
Action: "create",
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
"blorp": {
|
|
|
|
Action: "delete",
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
"honk": {
|
|
|
|
Action: "update",
|
|
|
|
Sensitive: false,
|
|
|
|
},
|
|
|
|
"secret": {
|
|
|
|
Action: "create",
|
|
|
|
Sensitive: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !cmp.Equal(want, got) {
|
|
|
|
t.Fatalf("unexpected result\n%s", cmp.Diff(want, got))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-23 16:16:09 +01:00
|
|
|
func TestOutputs_String(t *testing.T) {
|
|
|
|
outputs := Outputs{
|
|
|
|
"boop": {
|
|
|
|
Sensitive: false,
|
|
|
|
Type: json.RawMessage(`"number"`),
|
|
|
|
Value: json.RawMessage(`1234`),
|
|
|
|
},
|
|
|
|
"beep": {
|
|
|
|
Sensitive: true,
|
|
|
|
Type: json.RawMessage(`"string"`),
|
|
|
|
Value: json.RawMessage(`"horse-battery"`),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if got, want := outputs.String(), "Outputs: 2"; got != want {
|
|
|
|
t.Fatalf("unexpected value\n got: %q\nwant: %q", got, want)
|
|
|
|
}
|
|
|
|
}
|