1/* 2Copyright 2014 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package net 18 19import ( 20 "net" 21 "reflect" 22 "sort" 23 "testing" 24) 25 26func parseIPNet(s string) *net.IPNet { 27 _, net, err := ParseCIDRSloppy(s) 28 if err != nil { 29 panic(err) 30 } 31 return net 32} 33 34func TestIPNets(t *testing.T) { 35 s := IPNetSet{} 36 s2 := IPNetSet{} 37 if len(s) != 0 { 38 t.Errorf("Expected len=0: %d", len(s)) 39 } 40 a := parseIPNet("1.0.0.0/8") 41 b := parseIPNet("2.0.0.0/8") 42 c := parseIPNet("3.0.0.0/8") 43 d := parseIPNet("4.0.0.0/8") 44 45 s.Insert(a, b) 46 if len(s) != 2 { 47 t.Errorf("Expected len=2: %d", len(s)) 48 } 49 s.Insert(c) 50 if s.Has(d) { 51 t.Errorf("Unexpected contents: %#v", s) 52 } 53 if !s.Has(a) { 54 t.Errorf("Missing contents: %#v", s) 55 } 56 s.Delete(a) 57 if s.Has(a) { 58 t.Errorf("Unexpected contents: %#v", s) 59 } 60 s.Insert(a) 61 if s.HasAll(a, b, d) { 62 t.Errorf("Unexpected contents: %#v", s) 63 } 64 if !s.HasAll(a, b) { 65 t.Errorf("Missing contents: %#v", s) 66 } 67 s2.Insert(a, b, d) 68 if s.IsSuperset(s2) { 69 t.Errorf("Unexpected contents: %#v", s) 70 } 71 s2.Delete(d) 72 if !s.IsSuperset(s2) { 73 t.Errorf("Missing contents: %#v", s) 74 } 75} 76 77func TestIPNetSetDeleteMultiples(t *testing.T) { 78 s := IPNetSet{} 79 a := parseIPNet("1.0.0.0/8") 80 b := parseIPNet("2.0.0.0/8") 81 c := parseIPNet("3.0.0.0/8") 82 83 s.Insert(a, b, c) 84 if len(s) != 3 { 85 t.Errorf("Expected len=3: %d", len(s)) 86 } 87 88 s.Delete(a, c) 89 if len(s) != 1 { 90 t.Errorf("Expected len=1: %d", len(s)) 91 } 92 if s.Has(a) { 93 t.Errorf("Unexpected contents: %#v", s) 94 } 95 if s.Has(c) { 96 t.Errorf("Unexpected contents: %#v", s) 97 } 98 if !s.Has(b) { 99 t.Errorf("Missing contents: %#v", s) 100 } 101} 102 103func TestNewIPNetSet(t *testing.T) { 104 s, err := ParseIPNets("1.0.0.0/8", "2.0.0.0/8", "3.0.0.0/8") 105 if err != nil { 106 t.Errorf("error parsing IPNets: %v", err) 107 } 108 if len(s) != 3 { 109 t.Errorf("Expected len=3: %d", len(s)) 110 } 111 a := parseIPNet("1.0.0.0/8") 112 b := parseIPNet("2.0.0.0/8") 113 c := parseIPNet("3.0.0.0/8") 114 115 if !s.Has(a) || !s.Has(b) || !s.Has(c) { 116 t.Errorf("Unexpected contents: %#v", s) 117 } 118} 119 120func TestIPNetSetDifference(t *testing.T) { 121 l, err := ParseIPNets("1.0.0.0/8", "2.0.0.0/8", "3.0.0.0/8") 122 if err != nil { 123 t.Errorf("error parsing IPNets: %v", err) 124 } 125 r, err := ParseIPNets("1.0.0.0/8", "2.0.0.0/8", "4.0.0.0/8", "5.0.0.0/8") 126 if err != nil { 127 t.Errorf("error parsing IPNets: %v", err) 128 } 129 c := l.Difference(r) 130 d := r.Difference(l) 131 if len(c) != 1 { 132 t.Errorf("Expected len=1: %d", len(c)) 133 } 134 if !c.Has(parseIPNet("3.0.0.0/8")) { 135 t.Errorf("Unexpected contents: %#v", c) 136 } 137 if len(d) != 2 { 138 t.Errorf("Expected len=2: %d", len(d)) 139 } 140 if !d.Has(parseIPNet("4.0.0.0/8")) || !d.Has(parseIPNet("5.0.0.0/8")) { 141 t.Errorf("Unexpected contents: %#v", d) 142 } 143} 144 145func TestIPNetSetList(t *testing.T) { 146 s, err := ParseIPNets("3.0.0.0/8", "1.0.0.0/8", "2.0.0.0/8") 147 if err != nil { 148 t.Errorf("error parsing IPNets: %v", err) 149 } 150 l := s.StringSlice() 151 sort.Strings(l) 152 if !reflect.DeepEqual(l, []string{"1.0.0.0/8", "2.0.0.0/8", "3.0.0.0/8"}) { 153 t.Errorf("List gave unexpected result: %#v", l) 154 } 155} 156 157func TestIPSet(t *testing.T) { 158 s := IPSet{} 159 s2 := IPSet{} 160 161 a := ParseIPSloppy("1.0.0.0") 162 b := ParseIPSloppy("2.0.0.0") 163 c := ParseIPSloppy("3.0.0.0") 164 d := ParseIPSloppy("4.0.0.0") 165 166 s.Insert(a, b) 167 if len(s) != 2 { 168 t.Errorf("Expected len=2: %d", len(s)) 169 } 170 if !s.Has(a) { 171 t.Errorf("Missing contents: %#v", s) 172 } 173 174 s.Insert(c) 175 if s.Has(d) { 176 t.Errorf("Unexpected contents: %#v", s) 177 } 178 179 s.Delete(a) 180 if s.Has(a) { 181 t.Errorf("Unexpected contents: %#v", s) 182 } 183 s.Insert(a) 184 if s.HasAll(a, b, d) { 185 t.Errorf("Unexpected contents: %#v", s) 186 } 187 if !s.HasAll(a, b) { 188 t.Errorf("Missing contents: %#v", s) 189 } 190 s2.Insert(a, b, d) 191 if s.IsSuperset(s2) { 192 t.Errorf("Unexpected contents: %#v", s) 193 } 194 s2.Delete(d) 195 if !s.IsSuperset(s2) { 196 t.Errorf("Missing contents: %#v", s) 197 } 198} 199 200func TestIPSetDeleteMultiples(t *testing.T) { 201 s := IPSet{} 202 a := ParseIPSloppy("1.0.0.0") 203 b := ParseIPSloppy("2.0.0.0") 204 c := ParseIPSloppy("3.0.0.0") 205 206 s.Insert(a, b, c) 207 if len(s) != 3 { 208 t.Errorf("Expected len=3: %d", len(s)) 209 } 210 211 s.Delete(a, c) 212 if len(s) != 1 { 213 t.Errorf("Expected len=1: %d", len(s)) 214 } 215 if s.Has(a) { 216 t.Errorf("Unexpected contents: %#v", s) 217 } 218 if s.Has(c) { 219 t.Errorf("Unexpected contents: %#v", s) 220 } 221 if !s.Has(b) { 222 t.Errorf("Missing contents: %#v", s) 223 } 224} 225 226func TestParseIPSet(t *testing.T) { 227 s, err := ParseIPSet("1.0.0.0", "2.0.0.0", "3.0.0.0", "::ffff:4.0.0.0") 228 if err != nil { 229 t.Errorf("error parsing IPSet: %v", err) 230 } 231 if len(s) != 4 { 232 t.Errorf("Expected len=3: %d", len(s)) 233 } 234 a := ParseIPSloppy("1.0.0.0") 235 b := ParseIPSloppy("2.0.0.0") 236 c := ParseIPSloppy("3.0.0.0") 237 d := ParseIPSloppy("::ffff:4.0.0.0") 238 e := ParseIPSloppy("4.0.0.0") 239 240 if !s.Has(a) || !s.Has(b) || !s.Has(c) || !s.Has(d) || !s.Has(e) { 241 t.Errorf("Unexpected contents: %#v", s) 242 } 243} 244 245func TestIPSetDifference(t *testing.T) { 246 l, err := ParseIPSet("1.0.0.0", "2.0.0.0", "3.0.0.0") 247 if err != nil { 248 t.Errorf("error parsing IPSet: %v", err) 249 } 250 r, err := ParseIPSet("1.0.0.0", "2.0.0.0", "4.0.0.0", "5.0.0.0") 251 if err != nil { 252 t.Errorf("error parsing IPSet: %v", err) 253 } 254 c := l.Difference(r) 255 d := r.Difference(l) 256 if len(c) != 1 { 257 t.Errorf("Expected len=1: %d", len(c)) 258 } 259 if !c.Has(ParseIPSloppy("3.0.0.0")) { 260 t.Errorf("Unexpected contents: %#v", c) 261 } 262 if len(d) != 2 { 263 t.Errorf("Expected len=2: %d", len(d)) 264 } 265 if !d.Has(ParseIPSloppy("4.0.0.0")) || !d.Has(ParseIPSloppy("5.0.0.0")) { 266 t.Errorf("Unexpected contents: %#v", d) 267 } 268} 269 270func TestIPSetList(t *testing.T) { 271 // NOTE: IPv4-in-IPv6 addresses are represented as IPv4 in its string value 272 s, err := ParseIPSet("3.0.0.0", "1.0.0.0", "2.0.0.0", "::ffff:1.2.3.4") 273 if err != nil { 274 t.Errorf("error parsing IPSet: %v", err) 275 } 276 277 l := s.StringSlice() 278 sort.Strings(l) 279 if !reflect.DeepEqual(l, []string{"1.0.0.0", "1.2.3.4", "2.0.0.0", "3.0.0.0"}) { 280 t.Errorf("List gave unexpected result: %#v", l) 281 } 282} 283 284func TestIPSetEqual(t *testing.T) { 285 // IPv4-in-IPv6 addresses are equal to their IPv4 equivalents 286 set1, err := ParseIPSet("1.0.0.0", "2.0.0.0", "3.0.0.0", "::ffff:4.0.0.0") 287 if err != nil { 288 t.Errorf("error parsing IPSet: %v", err) 289 } 290 291 set2, err := ParseIPSet("1.0.0.0", "2.0.0.0", "3.0.0.0", "4.0.0.0") 292 if err != nil { 293 t.Errorf("error parsing IPSet: %v", err) 294 } 295 296 if !set1.Equal(set2) { 297 t.Errorf("sets %v and %v are not equal", set1, set2) 298 } 299 300 // order shouldn't matter 301 set1, err = ParseIPSet("1.0.0.0", "2.0.0.0", "3.0.0.0") 302 if err != nil { 303 t.Errorf("error parsing IPSet: %v", err) 304 } 305 306 set2, err = ParseIPSet("3.0.0.0", "1.0.0.0", "2.0.0.0") 307 if err != nil { 308 t.Errorf("error parsing IPSet: %v", err) 309 } 310 311 if !set1.Equal(set2) { 312 t.Errorf("sets %v and %v are not equal", set1, set2) 313 } 314} 315