github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/fingerprint/network_test.go (about) 1 package fingerprint 2 3 import ( 4 "fmt" 5 "net" 6 "testing" 7 8 "github.com/hashicorp/nomad/client/config" 9 "github.com/hashicorp/nomad/nomad/structs" 10 ) 11 12 var ( 13 lo = net.Interface{ 14 Index: 2, 15 MTU: 65536, 16 Name: "lo", 17 HardwareAddr: []byte{23, 43, 54, 54}, 18 Flags: net.FlagUp | net.FlagLoopback, 19 } 20 21 eth0 = net.Interface{ 22 Index: 3, 23 MTU: 1500, 24 Name: "eth0", 25 HardwareAddr: []byte{23, 44, 54, 67}, 26 Flags: net.FlagUp | net.FlagMulticast | net.FlagBroadcast, 27 } 28 29 eth1 = net.Interface{ 30 Index: 4, 31 MTU: 1500, 32 Name: "eth1", 33 HardwareAddr: []byte{23, 44, 54, 69}, 34 Flags: net.FlagMulticast | net.FlagBroadcast, 35 } 36 37 eth2 = net.Interface{ 38 Index: 4, 39 MTU: 1500, 40 Name: "eth2", 41 HardwareAddr: []byte{23, 44, 54, 70}, 42 Flags: net.FlagUp | net.FlagBroadcast | net.FlagMulticast, 43 } 44 ) 45 46 // A fake network detector which returns no devices 47 type NetworkIntefaceDetectorNoDevices struct { 48 } 49 50 func (f *NetworkIntefaceDetectorNoDevices) Interfaces() ([]net.Interface, error) { 51 return make([]net.Interface, 0), nil 52 } 53 54 func (f *NetworkIntefaceDetectorNoDevices) InterfaceByName(name string) (*net.Interface, error) { 55 return nil, fmt.Errorf("Device with name %s doesn't exist", name) 56 } 57 58 func (f *NetworkIntefaceDetectorNoDevices) Addrs(intf *net.Interface) ([]net.Addr, error) { 59 return nil, fmt.Errorf("No interfaces found for device %v", intf.Name) 60 } 61 62 // A fake network detector which returns only loopback 63 type NetworkInterfaceDetectorOnlyLo struct { 64 } 65 66 func (n *NetworkInterfaceDetectorOnlyLo) Interfaces() ([]net.Interface, error) { 67 return []net.Interface{lo}, nil 68 } 69 70 func (n *NetworkInterfaceDetectorOnlyLo) InterfaceByName(name string) (*net.Interface, error) { 71 if name == "lo" { 72 return &lo, nil 73 } 74 75 return nil, fmt.Errorf("No device with name %v found", name) 76 } 77 78 func (n *NetworkInterfaceDetectorOnlyLo) Addrs(intf *net.Interface) ([]net.Addr, error) { 79 if intf.Name == "lo" { 80 _, ipnet1, _ := net.ParseCIDR("127.0.0.1/8") 81 _, ipnet2, _ := net.ParseCIDR("2001:DB8::/48") 82 return []net.Addr{ipnet1, ipnet2}, nil 83 } 84 85 return nil, fmt.Errorf("Can't find addresses for device: %v", intf.Name) 86 } 87 88 // A fake network detector which simulates the presence of multiple interfaces 89 type NetworkInterfaceDetectorMultipleInterfaces struct { 90 } 91 92 func (n *NetworkInterfaceDetectorMultipleInterfaces) Interfaces() ([]net.Interface, error) { 93 return []net.Interface{lo, eth0, eth1, eth2}, nil 94 } 95 96 func (n *NetworkInterfaceDetectorMultipleInterfaces) InterfaceByName(name string) (*net.Interface, error) { 97 var intf *net.Interface 98 switch name { 99 case "lo": 100 intf = &lo 101 case "eth0": 102 intf = ð0 103 case "eth1": 104 intf = ð1 105 case "eth2": 106 intf = ð2 107 } 108 if intf != nil { 109 return intf, nil 110 } 111 112 return nil, fmt.Errorf("No device with name %v found", name) 113 } 114 115 func (n *NetworkInterfaceDetectorMultipleInterfaces) Addrs(intf *net.Interface) ([]net.Addr, error) { 116 if intf.Name == "lo" { 117 _, ipnet1, _ := net.ParseCIDR("127.0.0.1/8") 118 _, ipnet2, _ := net.ParseCIDR("2001:DB8::/48") 119 return []net.Addr{ipnet1, ipnet2}, nil 120 } 121 122 if intf.Name == "eth0" { 123 _, ipnet1, _ := net.ParseCIDR("100.64.0.11/10") 124 _, ipnet2, _ := net.ParseCIDR("2005:DB6::/48") 125 return []net.Addr{ipnet1, ipnet2}, nil 126 } 127 128 if intf.Name == "eth1" { 129 _, ipnet1, _ := net.ParseCIDR("100.64.0.10/10") 130 _, ipnet2, _ := net.ParseCIDR("2003:DB8::/48") 131 return []net.Addr{ipnet1, ipnet2}, nil 132 } 133 134 if intf.Name == "eth2" { 135 return []net.Addr{}, nil 136 } 137 return nil, fmt.Errorf("Can't find addresses for device: %v", intf.Name) 138 } 139 140 func TestNetworkFingerprint_basic(t *testing.T) { 141 f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &DefaultNetworkInterfaceDetector{}} 142 node := &structs.Node{ 143 Attributes: make(map[string]string), 144 } 145 cfg := &config.Config{NetworkSpeed: 100} 146 147 ok, err := f.Fingerprint(cfg, node) 148 if err != nil { 149 t.Fatalf("err: %v", err) 150 } 151 if !ok { 152 t.Fatalf("should apply") 153 } 154 155 assertNodeAttributeContains(t, node, "unique.network.ip-address") 156 157 ip := node.Attributes["unique.network.ip-address"] 158 match := net.ParseIP(ip) 159 if match == nil { 160 t.Fatalf("Bad IP match: %s", ip) 161 } 162 163 if node.Resources == nil || len(node.Resources.Networks) == 0 { 164 t.Fatal("Expected to find Network Resources") 165 } 166 167 // Test at least the first Network Resource 168 net := node.Resources.Networks[0] 169 if net.IP == "" { 170 t.Fatal("Expected Network Resource to not be empty") 171 } 172 if net.CIDR == "" { 173 t.Fatal("Expected Network Resource to have a CIDR") 174 } 175 if net.Device == "" { 176 t.Fatal("Expected Network Resource to have a Device Name") 177 } 178 if net.MBits == 0 { 179 t.Fatal("Expected Network Resource to have a non-zero bandwith") 180 } 181 } 182 183 func TestNetworkFingerprint_no_devices(t *testing.T) { 184 f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &NetworkIntefaceDetectorNoDevices{}} 185 node := &structs.Node{ 186 Attributes: make(map[string]string), 187 } 188 cfg := &config.Config{NetworkSpeed: 100} 189 190 ok, err := f.Fingerprint(cfg, node) 191 if err != nil { 192 t.Fatalf("err: %v", err) 193 } 194 195 if ok { 196 t.Fatalf("ok: %v", ok) 197 } 198 } 199 200 func TestNetworkFingerprint_default_device_absent(t *testing.T) { 201 f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &NetworkInterfaceDetectorOnlyLo{}} 202 node := &structs.Node{ 203 Attributes: make(map[string]string), 204 } 205 cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "eth0"} 206 207 ok, err := f.Fingerprint(cfg, node) 208 if err == nil { 209 t.Fatalf("err: %v", err) 210 } 211 212 if ok { 213 t.Fatalf("ok: %v", ok) 214 } 215 } 216 217 func TestNetworkFingerPrint_default_device(t *testing.T) { 218 f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &NetworkInterfaceDetectorOnlyLo{}} 219 node := &structs.Node{ 220 Attributes: make(map[string]string), 221 } 222 cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "lo"} 223 224 ok, err := f.Fingerprint(cfg, node) 225 if err != nil { 226 t.Fatalf("err: %v", err) 227 } 228 if !ok { 229 t.Fatalf("should apply") 230 } 231 232 assertNodeAttributeContains(t, node, "unique.network.ip-address") 233 234 ip := node.Attributes["unique.network.ip-address"] 235 match := net.ParseIP(ip) 236 if match == nil { 237 t.Fatalf("Bad IP match: %s", ip) 238 } 239 240 if node.Resources == nil || len(node.Resources.Networks) == 0 { 241 t.Fatal("Expected to find Network Resources") 242 } 243 244 // Test at least the first Network Resource 245 net := node.Resources.Networks[0] 246 if net.IP == "" { 247 t.Fatal("Expected Network Resource to not be empty") 248 } 249 if net.CIDR == "" { 250 t.Fatal("Expected Network Resource to have a CIDR") 251 } 252 if net.Device == "" { 253 t.Fatal("Expected Network Resource to have a Device Name") 254 } 255 if net.MBits == 0 { 256 t.Fatal("Expected Network Resource to have a non-zero bandwith") 257 } 258 } 259 260 func TestNetworkFingerPrint_excludelo_down_interfaces(t *testing.T) { 261 f := &NetworkFingerprint{logger: testLogger(), interfaceDetector: &NetworkInterfaceDetectorMultipleInterfaces{}} 262 node := &structs.Node{ 263 Attributes: make(map[string]string), 264 } 265 cfg := &config.Config{NetworkSpeed: 100} 266 267 ok, err := f.Fingerprint(cfg, node) 268 if err != nil { 269 t.Fatalf("err: %v", err) 270 } 271 if !ok { 272 t.Fatalf("should apply") 273 } 274 275 assertNodeAttributeContains(t, node, "unique.network.ip-address") 276 277 ip := node.Attributes["unique.network.ip-address"] 278 match := net.ParseIP(ip) 279 if match == nil { 280 t.Fatalf("Bad IP match: %s", ip) 281 } 282 283 if node.Resources == nil || len(node.Resources.Networks) == 0 { 284 t.Fatal("Expected to find Network Resources") 285 } 286 287 // Test at least the first Network Resource 288 net := node.Resources.Networks[0] 289 if net.IP == "" { 290 t.Fatal("Expected Network Resource to have an IP") 291 } 292 if net.CIDR == "" { 293 t.Fatal("Expected Network Resource to have a CIDR") 294 } 295 if net.Device != "eth0" { 296 t.Fatal("Expected Network Resource to be eth0. Actual: ", net.Device) 297 } 298 if net.MBits == 0 { 299 t.Fatal("Expected Network Resource to have a non-zero bandwith") 300 } 301 }