github.com/opentofu/opentofu@v1.7.1/internal/legacy/helper/schema/backend_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package schema 7 8 import ( 9 "context" 10 "fmt" 11 "testing" 12 13 "github.com/zclconf/go-cty/cty" 14 ) 15 16 func TestBackendPrepare(t *testing.T) { 17 cases := []struct { 18 Name string 19 B *Backend 20 Config map[string]cty.Value 21 Expect map[string]cty.Value 22 Err bool 23 }{ 24 { 25 "Basic required field", 26 &Backend{ 27 Schema: map[string]*Schema{ 28 "foo": &Schema{ 29 Required: true, 30 Type: TypeString, 31 }, 32 }, 33 }, 34 map[string]cty.Value{}, 35 map[string]cty.Value{}, 36 true, 37 }, 38 39 { 40 "Null config", 41 &Backend{ 42 Schema: map[string]*Schema{ 43 "foo": &Schema{ 44 Required: true, 45 Type: TypeString, 46 }, 47 }, 48 }, 49 nil, 50 map[string]cty.Value{}, 51 true, 52 }, 53 54 { 55 "Basic required field set", 56 &Backend{ 57 Schema: map[string]*Schema{ 58 "foo": &Schema{ 59 Required: true, 60 Type: TypeString, 61 }, 62 }, 63 }, 64 map[string]cty.Value{ 65 "foo": cty.StringVal("bar"), 66 }, 67 map[string]cty.Value{ 68 "foo": cty.StringVal("bar"), 69 }, 70 false, 71 }, 72 73 { 74 "unused default", 75 &Backend{ 76 Schema: map[string]*Schema{ 77 "foo": &Schema{ 78 Optional: true, 79 Type: TypeString, 80 Default: "baz", 81 }, 82 }, 83 }, 84 map[string]cty.Value{ 85 "foo": cty.StringVal("bar"), 86 }, 87 map[string]cty.Value{ 88 "foo": cty.StringVal("bar"), 89 }, 90 false, 91 }, 92 93 { 94 "default", 95 &Backend{ 96 Schema: map[string]*Schema{ 97 "foo": &Schema{ 98 Type: TypeString, 99 Optional: true, 100 Default: "baz", 101 }, 102 }, 103 }, 104 map[string]cty.Value{}, 105 map[string]cty.Value{ 106 "foo": cty.StringVal("baz"), 107 }, 108 false, 109 }, 110 111 { 112 "default func", 113 &Backend{ 114 Schema: map[string]*Schema{ 115 "foo": &Schema{ 116 Type: TypeString, 117 Optional: true, 118 DefaultFunc: func() (interface{}, error) { 119 return "baz", nil 120 }, 121 }, 122 }, 123 }, 124 map[string]cty.Value{}, 125 map[string]cty.Value{ 126 "foo": cty.StringVal("baz"), 127 }, 128 false, 129 }, 130 } 131 132 for i, tc := range cases { 133 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 134 cfgVal := cty.NullVal(cty.Object(map[string]cty.Type{})) 135 if tc.Config != nil { 136 cfgVal = cty.ObjectVal(tc.Config) 137 } 138 configVal, diags := tc.B.PrepareConfig(cfgVal) 139 if diags.HasErrors() != tc.Err { 140 for _, d := range diags { 141 t.Error(d.Description()) 142 } 143 } 144 145 if tc.Err { 146 return 147 } 148 149 expect := cty.ObjectVal(tc.Expect) 150 if !expect.RawEquals(configVal) { 151 t.Fatalf("\nexpected: %#v\ngot: %#v\n", expect, configVal) 152 } 153 }) 154 } 155 } 156 157 func TestBackendConfigure(t *testing.T) { 158 cases := []struct { 159 Name string 160 B *Backend 161 Config map[string]cty.Value 162 Err bool 163 }{ 164 { 165 "Basic config", 166 &Backend{ 167 Schema: map[string]*Schema{ 168 "foo": &Schema{ 169 Type: TypeInt, 170 Optional: true, 171 }, 172 }, 173 174 ConfigureFunc: func(ctx context.Context) error { 175 d := FromContextBackendConfig(ctx) 176 if d.Get("foo").(int) != 42 { 177 return fmt.Errorf("bad config data") 178 } 179 180 return nil 181 }, 182 }, 183 map[string]cty.Value{ 184 "foo": cty.NumberIntVal(42), 185 }, 186 false, 187 }, 188 } 189 190 for i, tc := range cases { 191 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 192 diags := tc.B.Configure(cty.ObjectVal(tc.Config)) 193 if diags.HasErrors() != tc.Err { 194 t.Errorf("wrong number of diagnostics") 195 } 196 }) 197 } 198 }