github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/network/network_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package network_test 5 6 import ( 7 "net" 8 9 "github.com/juju/collections/set" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 corenetwork "github.com/juju/juju/core/network" 14 "github.com/juju/juju/network" 15 "github.com/juju/juju/testing" 16 ) 17 18 type InterfaceInfoSuite struct{} 19 20 var _ = gc.Suite(&InterfaceInfoSuite{}) 21 22 type RouteSuite struct{} 23 24 var _ = gc.Suite(&RouteSuite{}) 25 26 func checkRouteIsValid(c *gc.C, r corenetwork.Route) { 27 c.Check(r.Validate(), jc.ErrorIsNil) 28 } 29 30 func checkRouteErrEquals(c *gc.C, r corenetwork.Route, errString string) { 31 err := r.Validate() 32 c.Assert(err, gc.NotNil) 33 c.Check(err.Error(), gc.Equals, errString) 34 } 35 36 func (s *RouteSuite) TestValidIPv4(c *gc.C) { 37 checkRouteIsValid(c, corenetwork.Route{ 38 DestinationCIDR: "0.1.2.3/24", 39 GatewayIP: "0.1.2.1", 40 Metric: 20, 41 }) 42 } 43 44 func (s *RouteSuite) TestValidIPv6(c *gc.C) { 45 checkRouteIsValid(c, corenetwork.Route{ 46 DestinationCIDR: "2001:db8:a0b:12f0::1/64", 47 GatewayIP: "2001:db8:a0b:12f0::1", 48 Metric: 10, 49 }) 50 } 51 52 func (s *RouteSuite) TestInvalidMixedIP(c *gc.C) { 53 checkRouteErrEquals(c, corenetwork.Route{ 54 DestinationCIDR: "0.1.2.3/24", 55 GatewayIP: "2001:db8::1", 56 Metric: 10, 57 }, "DestinationCIDR is IPv4 (0.1.2.3/24) but GatewayIP is IPv6 (2001:db8::1)") 58 checkRouteErrEquals(c, corenetwork.Route{ 59 DestinationCIDR: "2001:db8::1/64", 60 GatewayIP: "0.1.2.1", 61 Metric: 10, 62 }, "DestinationCIDR is IPv6 (2001:db8::1/64) but GatewayIP is IPv4 (0.1.2.1)") 63 } 64 65 func (s *RouteSuite) TestInvalidNotCIDR(c *gc.C) { 66 checkRouteErrEquals(c, corenetwork.Route{ 67 DestinationCIDR: "0.1.2.3", 68 GatewayIP: "0.1.2.1", 69 Metric: 10, 70 }, "DestinationCIDR not valid: invalid CIDR address: 0.1.2.3") 71 checkRouteErrEquals(c, corenetwork.Route{ 72 DestinationCIDR: "2001:db8::2", 73 GatewayIP: "2001:db8::1", 74 Metric: 10, 75 }, "DestinationCIDR not valid: invalid CIDR address: 2001:db8::2") 76 } 77 78 func (s *RouteSuite) TestInvalidNotIP(c *gc.C) { 79 checkRouteErrEquals(c, corenetwork.Route{ 80 DestinationCIDR: "0.1.2.3/24", 81 GatewayIP: "0.1.2.1/16", 82 Metric: 10, 83 }, `GatewayIP is not a valid IP address: "0.1.2.1/16"`) 84 checkRouteErrEquals(c, corenetwork.Route{ 85 DestinationCIDR: "0.1.2.3/24", 86 GatewayIP: "", 87 Metric: 10, 88 }, `GatewayIP is not a valid IP address: ""`) 89 checkRouteErrEquals(c, corenetwork.Route{ 90 DestinationCIDR: "2001:db8::2/64", 91 GatewayIP: "", 92 Metric: 10, 93 }, `GatewayIP is not a valid IP address: ""`) 94 } 95 96 func (s *RouteSuite) TestInvalidMetric(c *gc.C) { 97 checkRouteErrEquals(c, corenetwork.Route{ 98 DestinationCIDR: "0.1.2.3/24", 99 GatewayIP: "0.1.2.1", 100 Metric: -1, 101 }, `Metric is negative: -1`) 102 } 103 104 type NetworkSuite struct { 105 testing.BaseSuite 106 } 107 108 var _ = gc.Suite(&NetworkSuite{}) 109 110 func (s *NetworkSuite) TestFilterBridgeAddresses(c *gc.C) { 111 s.PatchValue(&network.AddressesForInterfaceName, func(name string) ([]string, error) { 112 if name == network.DefaultLXDBridge { 113 return []string{ 114 "10.0.4.1", 115 "10.0.5.1/24", 116 }, nil 117 } else if name == network.DefaultKVMBridge { 118 return []string{ 119 "192.168.122.1", 120 }, nil 121 } 122 c.Fatalf("unknown bridge name: %q", name) 123 return nil, nil 124 }) 125 126 inputAddresses := corenetwork.NewMachineAddresses([]string{ 127 "127.0.0.1", 128 "2001:db8::1", 129 "10.0.0.1", 130 "10.0.4.1", // filtered (directly from LXD bridge) 131 "10.0.5.10", // filtered (from LXD bridge, 10.0.5.1/24) 132 "10.0.6.10", // unfiltered 133 "192.168.122.1", // filtered (from virbr0 bridge, 192.168.122.1) 134 "192.168.123.42", 135 "localhost", // unfiltered because it isn't an IP address 136 "252.16.134.1", // unfiltered Class E reserved address, used by Fan. 137 }).AsProviderAddresses() 138 filteredAddresses := corenetwork.NewMachineAddresses([]string{ 139 "127.0.0.1", 140 "2001:db8::1", 141 "10.0.0.1", 142 "10.0.6.10", 143 "192.168.123.42", 144 "localhost", 145 "252.16.134.1", 146 }).AsProviderAddresses() 147 c.Assert(network.FilterBridgeAddresses(inputAddresses), jc.DeepEquals, filteredAddresses) 148 } 149 150 func checkQuoteSpaceSet(c *gc.C, expected string, spaces ...string) { 151 spaceSet := set.NewStrings(spaces...) 152 c.Check(network.QuoteSpaceSet(spaceSet), gc.Equals, expected) 153 } 154 155 func (s *NetworkSuite) TestQuoteSpaceSet(c *gc.C) { 156 // Only the 'empty string' space 157 checkQuoteSpaceSet(c, `""`, "") 158 // No spaces 159 checkQuoteSpaceSet(c, `<none>`) 160 // One space 161 checkQuoteSpaceSet(c, `"a"`, "a") 162 // Two spaces are sorted 163 checkQuoteSpaceSet(c, `"a", "b"`, "a", "b") 164 checkQuoteSpaceSet(c, `"a", "b"`, "b", "a") 165 // Mixed 166 checkQuoteSpaceSet(c, `"", "b"`, "b", "") 167 } 168 169 type CIDRSuite struct { 170 testing.BaseSuite 171 } 172 173 var _ = gc.Suite(&CIDRSuite{}) 174 175 func (s *CIDRSuite) TestSubnetInAnyRange(c *gc.C) { 176 type test struct { 177 cidrs []string 178 subnet string 179 included bool 180 } 181 182 tests := []*test{ 183 { 184 cidrs: []string{ 185 "192.168.8.0/21", 186 "192.168.20.0/24", 187 }, 188 subnet: "192.168.8.0/24", 189 included: true, 190 }, { 191 cidrs: []string{ 192 "192.168.8.0/21", 193 "192.168.20.0/24", 194 }, 195 subnet: "192.168.12.128/26", 196 included: true, 197 }, { 198 cidrs: []string{ 199 "192.168.8.0/21", 200 "192.168.20.0/24", 201 }, 202 subnet: "192.168.20.128/27", 203 included: true, 204 }, { 205 cidrs: []string{ 206 "192.168.8.0/21", 207 "192.168.20.0/24", 208 }, 209 subnet: "192.168.15.255/32", 210 included: true, 211 }, { 212 cidrs: []string{ 213 "192.168.8.0/21", 214 "192.168.20.0/24", 215 }, 216 subnet: "192.168.16.64/26", 217 included: false, 218 }, { 219 cidrs: []string{ 220 "2620:0:2d0:200:0:0:0:10/116", 221 "2630:0:2d0:200:0:0:0:10/120", 222 }, 223 subnet: "2620:0:2d0:200:0:0:0:0/124", 224 included: true, 225 }, { 226 cidrs: []string{ 227 "2620:0:2d0:200:0:0:0:10/116", 228 "2630:0:2d0:200:0:0:0:10/120", 229 }, 230 subnet: "2620:0:2d0:200:0:0:0:10/128", 231 included: true, 232 }, { 233 cidrs: []string{ 234 "2620:0:2d0:200:0:0:0:10/116", 235 "2630:0:2d0:200:0:0:0:10/120", 236 }, 237 subnet: "2620:0:2d0:200:0:0:20:10/120", 238 included: false, 239 }, 240 } 241 242 for i, t := range tests { 243 c.Logf("test %d: %v in %v?", i, t.subnet, t.cidrs) 244 cidrs := make([]*net.IPNet, len(t.cidrs)) 245 for i, cidrStr := range t.cidrs { 246 _, cidr, err := net.ParseCIDR(cidrStr) 247 c.Assert(err, jc.ErrorIsNil) 248 cidrs[i] = cidr 249 } 250 _, subnet, err := net.ParseCIDR(t.subnet) 251 c.Assert(err, jc.ErrorIsNil) 252 result := network.SubnetInAnyRange(cidrs, subnet) 253 c.Assert(result, gc.Equals, t.included) 254 } 255 }