github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/lang/funcs/sensitive_test.go (about) 1 package funcs 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/zclconf/go-cty/cty" 8 ) 9 10 func TestSensitive(t *testing.T) { 11 tests := []struct { 12 Input cty.Value 13 WantErr string 14 }{ 15 { 16 cty.NumberIntVal(1), 17 ``, 18 }, 19 { 20 // Unknown values stay unknown while becoming sensitive 21 cty.UnknownVal(cty.String), 22 ``, 23 }, 24 { 25 // Null values stay unknown while becoming sensitive 26 cty.NullVal(cty.String), 27 ``, 28 }, 29 { 30 // DynamicVal can be marked as sensitive 31 cty.DynamicVal, 32 ``, 33 }, 34 { 35 // The marking is shallow only 36 cty.ListVal([]cty.Value{cty.NumberIntVal(1)}), 37 ``, 38 }, 39 { 40 // A value already marked is allowed and stays marked 41 cty.NumberIntVal(1).Mark("sensitive"), 42 ``, 43 }, 44 { 45 // A value with some non-standard mark gets "fixed" to be marked 46 // with the standard "sensitive" mark. (This situation occurring 47 // would imply an inconsistency/bug elsewhere, so we're just 48 // being robust about it here.) 49 cty.NumberIntVal(1).Mark("bloop"), 50 ``, 51 }, 52 { 53 // A value deep already marked is allowed and stays marked, 54 // _and_ we'll also mark the outer collection as sensitive. 55 cty.ListVal([]cty.Value{cty.NumberIntVal(1).Mark("sensitive")}), 56 ``, 57 }, 58 } 59 60 for _, test := range tests { 61 t.Run(fmt.Sprintf("sensitive(%#v)", test.Input), func(t *testing.T) { 62 got, err := Sensitive(test.Input) 63 64 if test.WantErr != "" { 65 if err == nil { 66 t.Fatal("succeeded; want error") 67 } 68 if got, want := err.Error(), test.WantErr; got != want { 69 t.Fatalf("wrong error\ngot: %s\nwant: %s", got, want) 70 } 71 return 72 } else if err != nil { 73 t.Fatalf("unexpected error: %s", err) 74 } 75 76 if !got.HasMark("sensitive") { 77 t.Errorf("result is not marked sensitive") 78 } 79 80 gotRaw, gotMarks := got.Unmark() 81 if len(gotMarks) != 1 { 82 // We're only expecting to have the "sensitive" mark we checked 83 // above. Any others are an error, even if they happen to 84 // appear alongside "sensitive". (We might change this rule 85 // if someday we decide to use marks for some additional 86 // unrelated thing in Terraform, but currently we assume that 87 // _all_ marks imply sensitive, and so returning any other 88 // marks would be confusing.) 89 t.Errorf("extraneous marks %#v", gotMarks) 90 } 91 92 // Disregarding shallow marks, the result should have the same 93 // effective value as the input. 94 wantRaw, _ := test.Input.Unmark() 95 if !gotRaw.RawEquals(wantRaw) { 96 t.Errorf("wrong unmarked result\ngot: %#v\nwant: %#v", got, wantRaw) 97 } 98 }) 99 } 100 } 101 102 func TestNonsensitive(t *testing.T) { 103 tests := []struct { 104 Input cty.Value 105 WantErr string 106 }{ 107 { 108 cty.NumberIntVal(1).Mark("sensitive"), 109 ``, 110 }, 111 { 112 cty.DynamicVal.Mark("sensitive"), 113 ``, 114 }, 115 { 116 cty.UnknownVal(cty.String).Mark("sensitive"), 117 ``, 118 }, 119 { 120 cty.NullVal(cty.EmptyObject).Mark("sensitive"), 121 ``, 122 }, 123 { 124 // The inner sensitive remains afterwards 125 cty.ListVal([]cty.Value{cty.NumberIntVal(1).Mark("sensitive")}).Mark("sensitive"), 126 ``, 127 }, 128 129 // Passing a value that is already non-sensitive is an error, 130 // because this function should always be used with specific 131 // intention, not just as a "make everything visible" hammer. 132 { 133 cty.NumberIntVal(1), 134 `the given value is not sensitive, so this call is redundant`, 135 }, 136 { 137 cty.NullVal(cty.String), 138 `the given value is not sensitive, so this call is redundant`, 139 }, 140 141 // Unknown values may become sensitive once they are known, so we 142 // permit them to be marked nonsensitive. 143 { 144 cty.DynamicVal, 145 ``, 146 }, 147 { 148 cty.UnknownVal(cty.String), 149 ``, 150 }, 151 } 152 153 for _, test := range tests { 154 t.Run(fmt.Sprintf("nonsensitive(%#v)", test.Input), func(t *testing.T) { 155 got, err := Nonsensitive(test.Input) 156 157 if test.WantErr != "" { 158 if err == nil { 159 t.Fatal("succeeded; want error") 160 } 161 if got, want := err.Error(), test.WantErr; got != want { 162 t.Fatalf("wrong error\ngot: %s\nwant: %s", got, want) 163 } 164 return 165 } else if err != nil { 166 t.Fatalf("unexpected error: %s", err) 167 } 168 169 if got.HasMark("sensitive") { 170 t.Errorf("result is still marked sensitive") 171 } 172 wantRaw, _ := test.Input.Unmark() 173 if !got.RawEquals(wantRaw) { 174 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Input) 175 } 176 }) 177 } 178 }