github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/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 = &eth0
   103  	case "eth1":
   104  		intf = &eth1
   105  	case "eth2":
   106  		intf = &eth2
   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  }