github.com/opentofu/opentofu@v1.7.1/internal/command/jsonchecks/checks_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 jsonchecks 7 8 import ( 9 "encoding/json" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 "github.com/opentofu/opentofu/internal/addrs" 14 "github.com/opentofu/opentofu/internal/checks" 15 "github.com/opentofu/opentofu/internal/states" 16 ) 17 18 func TestMarshalCheckStates(t *testing.T) { 19 resourceAAddr := addrs.ConfigCheckable(addrs.Resource{ 20 Mode: addrs.ManagedResourceMode, 21 Type: "test", 22 Name: "a", 23 }.InModule(addrs.RootModule)) 24 resourceAInstAddr := addrs.Checkable(addrs.Resource{ 25 Mode: addrs.ManagedResourceMode, 26 Type: "test", 27 Name: "a", 28 }.Instance(addrs.StringKey("foo")).Absolute(addrs.RootModuleInstance)) 29 moduleChildAddr := addrs.RootModuleInstance.Child("child", addrs.IntKey(0)) 30 resourceBAddr := addrs.ConfigCheckable(addrs.Resource{ 31 Mode: addrs.ManagedResourceMode, 32 Type: "test", 33 Name: "b", 34 }.InModule(moduleChildAddr.Module())) 35 resourceBInstAddr := addrs.Checkable(addrs.Resource{ 36 Mode: addrs.ManagedResourceMode, 37 Type: "test", 38 Name: "b", 39 }.Instance(addrs.NoKey).Absolute(moduleChildAddr)) 40 outputAAddr := addrs.ConfigCheckable(addrs.OutputValue{Name: "a"}.InModule(addrs.RootModule)) 41 outputAInstAddr := addrs.Checkable(addrs.OutputValue{Name: "a"}.Absolute(addrs.RootModuleInstance)) 42 outputBAddr := addrs.ConfigCheckable(addrs.OutputValue{Name: "b"}.InModule(moduleChildAddr.Module())) 43 outputBInstAddr := addrs.Checkable(addrs.OutputValue{Name: "b"}.Absolute(moduleChildAddr)) 44 checkBlockAAddr := addrs.ConfigCheckable(addrs.Check{Name: "a"}.InModule(addrs.RootModule)) 45 checkBlockAInstAddr := addrs.Checkable(addrs.Check{Name: "a"}.Absolute(addrs.RootModuleInstance)) 46 47 tests := map[string]struct { 48 Input *states.CheckResults 49 Want any 50 }{ 51 "empty": { 52 &states.CheckResults{}, 53 []any{}, 54 }, 55 "failures": { 56 &states.CheckResults{ 57 ConfigResults: addrs.MakeMap( 58 addrs.MakeMapElem(resourceAAddr, &states.CheckResultAggregate{ 59 Status: checks.StatusFail, 60 ObjectResults: addrs.MakeMap( 61 addrs.MakeMapElem(resourceAInstAddr, &states.CheckResultObject{ 62 Status: checks.StatusFail, 63 FailureMessages: []string{ 64 "Not enough boops.", 65 "Too many beeps.", 66 }, 67 }), 68 ), 69 }), 70 addrs.MakeMapElem(resourceBAddr, &states.CheckResultAggregate{ 71 Status: checks.StatusFail, 72 ObjectResults: addrs.MakeMap( 73 addrs.MakeMapElem(resourceBInstAddr, &states.CheckResultObject{ 74 Status: checks.StatusFail, 75 FailureMessages: []string{ 76 "Splines are too pointy.", 77 }, 78 }), 79 ), 80 }), 81 addrs.MakeMapElem(outputAAddr, &states.CheckResultAggregate{ 82 Status: checks.StatusFail, 83 ObjectResults: addrs.MakeMap( 84 addrs.MakeMapElem(outputAInstAddr, &states.CheckResultObject{ 85 Status: checks.StatusFail, 86 }), 87 ), 88 }), 89 addrs.MakeMapElem(outputBAddr, &states.CheckResultAggregate{ 90 Status: checks.StatusFail, 91 ObjectResults: addrs.MakeMap( 92 addrs.MakeMapElem(outputBInstAddr, &states.CheckResultObject{ 93 Status: checks.StatusFail, 94 FailureMessages: []string{ 95 "Not object-oriented enough.", 96 }, 97 }), 98 ), 99 }), 100 addrs.MakeMapElem(checkBlockAAddr, &states.CheckResultAggregate{ 101 Status: checks.StatusFail, 102 ObjectResults: addrs.MakeMap( 103 addrs.MakeMapElem(checkBlockAInstAddr, &states.CheckResultObject{ 104 Status: checks.StatusFail, 105 FailureMessages: []string{ 106 "Couldn't reverse the polarity.", 107 }, 108 }), 109 ), 110 }), 111 ), 112 }, 113 []any{ 114 map[string]any{ 115 "address": map[string]any{ 116 "kind": "check", 117 "to_display": "check.a", 118 "name": "a", 119 }, 120 "instances": []any{ 121 map[string]any{ 122 "address": map[string]any{ 123 "to_display": `check.a`, 124 }, 125 "problems": []any{ 126 map[string]any{ 127 "message": "Couldn't reverse the polarity.", 128 }, 129 }, 130 "status": "fail", 131 }, 132 }, 133 "status": "fail", 134 }, 135 map[string]any{ 136 "address": map[string]any{ 137 "kind": "output_value", 138 "module": "module.child", 139 "name": "b", 140 "to_display": "module.child.output.b", 141 }, 142 "instances": []any{ 143 map[string]any{ 144 "address": map[string]any{ 145 "module": "module.child[0]", 146 "to_display": "module.child[0].output.b", 147 }, 148 "problems": []any{ 149 map[string]any{ 150 "message": "Not object-oriented enough.", 151 }, 152 }, 153 "status": "fail", 154 }, 155 }, 156 "status": "fail", 157 }, 158 map[string]any{ 159 "address": map[string]any{ 160 "kind": "resource", 161 "mode": "managed", 162 "module": "module.child", 163 "name": "b", 164 "to_display": "module.child.test.b", 165 "type": "test", 166 }, 167 "instances": []any{ 168 map[string]any{ 169 "address": map[string]any{ 170 "module": "module.child[0]", 171 "to_display": "module.child[0].test.b", 172 }, 173 "problems": []any{ 174 map[string]any{ 175 "message": "Splines are too pointy.", 176 }, 177 }, 178 "status": "fail", 179 }, 180 }, 181 "status": "fail", 182 }, 183 map[string]any{ 184 "address": map[string]any{ 185 "kind": "output_value", 186 "name": "a", 187 "to_display": "output.a", 188 }, 189 "instances": []any{ 190 map[string]any{ 191 "address": map[string]any{ 192 "to_display": "output.a", 193 }, 194 "status": "fail", 195 }, 196 }, 197 "status": "fail", 198 }, 199 map[string]any{ 200 "address": map[string]any{ 201 "kind": "resource", 202 "mode": "managed", 203 "name": "a", 204 "to_display": "test.a", 205 "type": "test", 206 }, 207 "instances": []any{ 208 map[string]any{ 209 "address": map[string]any{ 210 "to_display": `test.a["foo"]`, 211 "instance_key": "foo", 212 }, 213 "problems": []any{ 214 map[string]any{ 215 "message": "Not enough boops.", 216 }, 217 map[string]any{ 218 "message": "Too many beeps.", 219 }, 220 }, 221 "status": "fail", 222 }, 223 }, 224 "status": "fail", 225 }, 226 }, 227 }, 228 } 229 230 for name, test := range tests { 231 t.Run(name, func(t *testing.T) { 232 gotBytes := MarshalCheckStates(test.Input) 233 234 var got any 235 err := json.Unmarshal(gotBytes, &got) 236 if err != nil { 237 t.Fatal(err) 238 } 239 240 if diff := cmp.Diff(test.Want, got); diff != "" { 241 t.Errorf("wrong result\n%s", diff) 242 } 243 }) 244 } 245 }