github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/lang/funcs/cidr_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 TestCidrHost(t *testing.T) { 11 tests := []struct { 12 Prefix cty.Value 13 Hostnum cty.Value 14 Want cty.Value 15 Err bool 16 }{ 17 { 18 cty.StringVal("192.168.1.0/24"), 19 cty.NumberIntVal(5), 20 cty.StringVal("192.168.1.5"), 21 false, 22 }, 23 { 24 cty.StringVal("192.168.1.0/24"), 25 cty.NumberIntVal(-5), 26 cty.StringVal("192.168.1.251"), 27 false, 28 }, 29 { 30 cty.StringVal("192.168.1.0/24"), 31 cty.NumberIntVal(-256), 32 cty.StringVal("192.168.1.0"), 33 false, 34 }, 35 { 36 cty.StringVal("192.168.1.0/30"), 37 cty.NumberIntVal(255), 38 cty.UnknownVal(cty.String), 39 true, // 255 doesn't fit in two bits 40 }, 41 { 42 cty.StringVal("192.168.1.0/30"), 43 cty.NumberIntVal(-255), 44 cty.UnknownVal(cty.String), 45 true, // 255 doesn't fit in two bits 46 }, 47 { 48 cty.StringVal("not-a-cidr"), 49 cty.NumberIntVal(6), 50 cty.UnknownVal(cty.String), 51 true, // not a valid CIDR mask 52 }, 53 { 54 cty.StringVal("10.256.0.0/8"), 55 cty.NumberIntVal(6), 56 cty.UnknownVal(cty.String), 57 true, // can't have an octet >255 58 }, 59 { // fractions are Not Ok 60 cty.StringVal("10.256.0.0/8"), 61 cty.NumberFloatVal(.75), 62 cty.UnknownVal(cty.String), 63 true, 64 }, 65 } 66 67 for _, test := range tests { 68 t.Run(fmt.Sprintf("cidrhost(%#v, %#v)", test.Prefix, test.Hostnum), func(t *testing.T) { 69 got, err := CidrHost(test.Prefix, test.Hostnum) 70 71 if test.Err { 72 if err == nil { 73 t.Fatal("succeeded; want error") 74 } 75 return 76 } else if err != nil { 77 t.Fatalf("unexpected error: %s", err) 78 } 79 80 if !got.RawEquals(test.Want) { 81 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 82 } 83 }) 84 } 85 } 86 87 func TestCidrNetmask(t *testing.T) { 88 tests := []struct { 89 Prefix cty.Value 90 Want cty.Value 91 Err bool 92 }{ 93 { 94 cty.StringVal("192.168.1.0/24"), 95 cty.StringVal("255.255.255.0"), 96 false, 97 }, 98 { 99 cty.StringVal("192.168.1.0/32"), 100 cty.StringVal("255.255.255.255"), 101 false, 102 }, 103 { 104 cty.StringVal("0.0.0.0/0"), 105 cty.StringVal("0.0.0.0"), 106 false, 107 }, 108 { 109 cty.StringVal("1::/64"), 110 cty.StringVal("ffff:ffff:ffff:ffff::"), 111 false, 112 }, 113 { 114 cty.StringVal("not-a-cidr"), 115 cty.UnknownVal(cty.String), 116 true, // not a valid CIDR mask 117 }, 118 { 119 cty.StringVal("110.256.0.0/8"), 120 cty.UnknownVal(cty.String), 121 true, // can't have an octet >255 122 }, 123 } 124 125 for _, test := range tests { 126 t.Run(fmt.Sprintf("cidrnetmask(%#v)", test.Prefix), func(t *testing.T) { 127 got, err := CidrNetmask(test.Prefix) 128 129 if test.Err { 130 if err == nil { 131 t.Fatal("succeeded; want error") 132 } 133 return 134 } else if err != nil { 135 t.Fatalf("unexpected error: %s", err) 136 } 137 138 if !got.RawEquals(test.Want) { 139 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 140 } 141 }) 142 } 143 } 144 145 func TestCidrSubnet(t *testing.T) { 146 tests := []struct { 147 Prefix cty.Value 148 Newbits cty.Value 149 Netnum cty.Value 150 Want cty.Value 151 Err bool 152 }{ 153 { 154 cty.StringVal("192.168.2.0/20"), 155 cty.NumberIntVal(4), 156 cty.NumberIntVal(6), 157 cty.StringVal("192.168.6.0/24"), 158 false, 159 }, 160 { 161 cty.StringVal("fe80::/48"), 162 cty.NumberIntVal(16), 163 cty.NumberIntVal(6), 164 cty.StringVal("fe80:0:0:6::/64"), 165 false, 166 }, 167 { // IPv4 address encoded in IPv6 syntax gets normalized 168 cty.StringVal("::ffff:192.168.0.0/112"), 169 cty.NumberIntVal(8), 170 cty.NumberIntVal(6), 171 cty.StringVal("192.168.6.0/24"), 172 false, 173 }, 174 { 175 cty.StringVal("fe80::/48"), 176 cty.NumberIntVal(33), 177 cty.NumberIntVal(6), 178 cty.StringVal("fe80::3:0:0:0/81"), 179 false, 180 }, 181 { // not enough bits left 182 cty.StringVal("192.168.0.0/30"), 183 cty.NumberIntVal(4), 184 cty.NumberIntVal(6), 185 cty.UnknownVal(cty.String), 186 true, 187 }, 188 { // can't encode 16 in 2 bits 189 cty.StringVal("192.168.0.0/168"), 190 cty.NumberIntVal(2), 191 cty.NumberIntVal(16), 192 cty.UnknownVal(cty.String), 193 true, 194 }, 195 { // not a valid CIDR mask 196 cty.StringVal("not-a-cidr"), 197 cty.NumberIntVal(4), 198 cty.NumberIntVal(6), 199 cty.UnknownVal(cty.String), 200 true, 201 }, 202 { // can't have an octet >255 203 cty.StringVal("10.256.0.0/8"), 204 cty.NumberIntVal(4), 205 cty.NumberIntVal(6), 206 cty.UnknownVal(cty.String), 207 true, 208 }, 209 { // fractions are Not Ok 210 cty.StringVal("10.256.0.0/8"), 211 cty.NumberFloatVal(2 / 3), 212 cty.NumberFloatVal(.75), 213 cty.UnknownVal(cty.String), 214 true, 215 }, 216 } 217 218 for _, test := range tests { 219 t.Run(fmt.Sprintf("cidrsubnet(%#v, %#v, %#v)", test.Prefix, test.Newbits, test.Netnum), func(t *testing.T) { 220 got, err := CidrSubnet(test.Prefix, test.Newbits, test.Netnum) 221 222 if test.Err { 223 if err == nil { 224 t.Fatal("succeeded; want error") 225 } 226 return 227 } else if err != nil { 228 t.Fatalf("unexpected error: %s", err) 229 } 230 231 if !got.RawEquals(test.Want) { 232 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 233 } 234 }) 235 } 236 } 237 func TestCidrSubnets(t *testing.T) { 238 tests := []struct { 239 Prefix cty.Value 240 Newbits []cty.Value 241 Want cty.Value 242 Err string 243 }{ 244 { 245 cty.StringVal("10.0.0.0/21"), 246 []cty.Value{ 247 cty.NumberIntVal(3), 248 cty.NumberIntVal(3), 249 cty.NumberIntVal(3), 250 cty.NumberIntVal(4), 251 cty.NumberIntVal(4), 252 cty.NumberIntVal(4), 253 cty.NumberIntVal(7), 254 cty.NumberIntVal(7), 255 cty.NumberIntVal(7), 256 }, 257 cty.ListVal([]cty.Value{ 258 cty.StringVal("10.0.0.0/24"), 259 cty.StringVal("10.0.1.0/24"), 260 cty.StringVal("10.0.2.0/24"), 261 cty.StringVal("10.0.3.0/25"), 262 cty.StringVal("10.0.3.128/25"), 263 cty.StringVal("10.0.4.0/25"), 264 cty.StringVal("10.0.4.128/28"), 265 cty.StringVal("10.0.4.144/28"), 266 cty.StringVal("10.0.4.160/28"), 267 }), 268 ``, 269 }, 270 { 271 cty.StringVal("10.0.0.0/30"), 272 []cty.Value{ 273 cty.NumberIntVal(1), 274 cty.NumberIntVal(3), 275 }, 276 cty.UnknownVal(cty.List(cty.String)), 277 `would extend prefix to 33 bits, which is too long for an IPv4 address`, 278 }, 279 { 280 cty.StringVal("10.0.0.0/8"), 281 []cty.Value{ 282 cty.NumberIntVal(1), 283 cty.NumberIntVal(1), 284 cty.NumberIntVal(1), 285 }, 286 cty.UnknownVal(cty.List(cty.String)), 287 `not enough remaining address space for a subnet with a prefix of 9 bits after 10.128.0.0/9`, 288 }, 289 { 290 cty.StringVal("10.0.0.0/8"), 291 []cty.Value{ 292 cty.NumberIntVal(1), 293 cty.NumberIntVal(0), 294 }, 295 cty.UnknownVal(cty.List(cty.String)), 296 `must extend prefix by at least one bit`, 297 }, 298 { 299 cty.StringVal("10.0.0.0/8"), 300 []cty.Value{ 301 cty.NumberIntVal(1), 302 cty.NumberIntVal(-1), 303 }, 304 cty.UnknownVal(cty.List(cty.String)), 305 `must extend prefix by at least one bit`, 306 }, 307 { 308 cty.StringVal("fe80::/48"), 309 []cty.Value{ 310 cty.NumberIntVal(1), 311 cty.NumberIntVal(33), 312 }, 313 cty.UnknownVal(cty.List(cty.String)), 314 `may not extend prefix by more than 32 bits`, 315 }, 316 } 317 318 for _, test := range tests { 319 t.Run(fmt.Sprintf("cidrsubnets(%#v, %#v)", test.Prefix, test.Newbits), func(t *testing.T) { 320 got, err := CidrSubnets(test.Prefix, test.Newbits...) 321 wantErr := test.Err != "" 322 323 if wantErr { 324 if err == nil { 325 t.Fatal("succeeded; want error") 326 } 327 if err.Error() != test.Err { 328 t.Fatalf("wrong error\ngot: %s\nwant: %s", err.Error(), test.Err) 329 } 330 return 331 } else if err != nil { 332 t.Fatalf("unexpected error: %s", err) 333 } 334 335 if !got.RawEquals(test.Want) { 336 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 337 } 338 }) 339 } 340 }