github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/nomad/structs/node_class_test.go (about)

     1  package structs
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  )
     7  
     8  func testNode() *Node {
     9  	return &Node{
    10  		ID:         GenerateUUID(),
    11  		Datacenter: "dc1",
    12  		Name:       "foobar",
    13  		Attributes: map[string]string{
    14  			"kernel.name": "linux",
    15  			"arch":        "x86",
    16  			"version":     "0.1.0",
    17  			"driver.exec": "1",
    18  		},
    19  		Resources: &Resources{
    20  			CPU:      4000,
    21  			MemoryMB: 8192,
    22  			DiskMB:   100 * 1024,
    23  			IOPS:     150,
    24  			Networks: []*NetworkResource{
    25  				&NetworkResource{
    26  					Device: "eth0",
    27  					CIDR:   "192.168.0.100/32",
    28  					MBits:  1000,
    29  				},
    30  			},
    31  		},
    32  		Links: map[string]string{
    33  			"consul": "foobar.dc1",
    34  		},
    35  		Meta: map[string]string{
    36  			"pci-dss": "true",
    37  		},
    38  		NodeClass: "linux-medium-pci",
    39  		Status:    NodeStatusReady,
    40  	}
    41  }
    42  
    43  func TestNode_ComputedClass(t *testing.T) {
    44  	// Create a node and gets it computed class
    45  	n := testNode()
    46  	if err := n.ComputeClass(); err != nil {
    47  		t.Fatalf("ComputeClass() failed: %v", err)
    48  	}
    49  	if n.ComputedClass == "" {
    50  		t.Fatal("ComputeClass() didn't set computed class")
    51  	}
    52  	old := n.ComputedClass
    53  
    54  	// Compute again to ensure determinism
    55  	if err := n.ComputeClass(); err != nil {
    56  		t.Fatalf("ComputeClass() failed: %v", err)
    57  	}
    58  	if old != n.ComputedClass {
    59  		t.Fatalf("ComputeClass() should have returned same class; got %v; want %v", n.ComputedClass, old)
    60  	}
    61  
    62  	// Modify a field and compute the class again.
    63  	n.Datacenter = "New DC"
    64  	if err := n.ComputeClass(); err != nil {
    65  		t.Fatalf("ComputeClass() failed: %v", err)
    66  	}
    67  	if n.ComputedClass == "" {
    68  		t.Fatal("ComputeClass() didn't set computed class")
    69  	}
    70  
    71  	if old == n.ComputedClass {
    72  		t.Fatal("ComputeClass() returned same computed class")
    73  	}
    74  }
    75  
    76  func TestNode_ComputedClass_Ignore(t *testing.T) {
    77  	// Create a node and gets it computed class
    78  	n := testNode()
    79  	if err := n.ComputeClass(); err != nil {
    80  		t.Fatalf("ComputeClass() failed: %v", err)
    81  	}
    82  	if n.ComputedClass == "" {
    83  		t.Fatal("ComputeClass() didn't set computed class")
    84  	}
    85  	old := n.ComputedClass
    86  
    87  	// Modify an ignored field and compute the class again.
    88  	n.ID = "New ID"
    89  	if err := n.ComputeClass(); err != nil {
    90  		t.Fatalf("ComputeClass() failed: %v", err)
    91  	}
    92  	if n.ComputedClass == "" {
    93  		t.Fatal("ComputeClass() didn't set computed class")
    94  	}
    95  
    96  	if old != n.ComputedClass {
    97  		t.Fatal("ComputeClass() should have ignored field")
    98  	}
    99  }
   100  
   101  func TestNode_ComputedClass_Attr(t *testing.T) {
   102  	// Create a node and gets it computed class
   103  	n := testNode()
   104  	if err := n.ComputeClass(); err != nil {
   105  		t.Fatalf("ComputeClass() failed: %v", err)
   106  	}
   107  	if n.ComputedClass == "" {
   108  		t.Fatal("ComputeClass() didn't set computed class")
   109  	}
   110  	old := n.ComputedClass
   111  
   112  	// Add a unique addr and compute the class again
   113  	n.Attributes["unique.foo"] = "bar"
   114  	if err := n.ComputeClass(); err != nil {
   115  		t.Fatalf("ComputeClass() failed: %v", err)
   116  	}
   117  	if old != n.ComputedClass {
   118  		t.Fatal("ComputeClass() didn't ignore unique attr suffix")
   119  	}
   120  
   121  	// Modify an attribute and compute the class again.
   122  	n.Attributes["version"] = "New Version"
   123  	if err := n.ComputeClass(); err != nil {
   124  		t.Fatalf("ComputeClass() failed: %v", err)
   125  	}
   126  	if n.ComputedClass == "" {
   127  		t.Fatal("ComputeClass() didn't set computed class")
   128  	}
   129  	if old == n.ComputedClass {
   130  		t.Fatal("ComputeClass() ignored attribute change")
   131  	}
   132  
   133  	// Remove and attribute and compute the class again.
   134  	old = n.ComputedClass
   135  	delete(n.Attributes, "driver.exec")
   136  	if err := n.ComputeClass(); err != nil {
   137  		t.Fatalf("ComputedClass() failed: %v", err)
   138  	}
   139  	if n.ComputedClass == "" {
   140  		t.Fatal("ComputeClass() didn't set computed class")
   141  	}
   142  	if old == n.ComputedClass {
   143  		t.Fatalf("ComputedClass() ignored removal of attribute key")
   144  	}
   145  }
   146  
   147  func TestNode_ComputedClass_Meta(t *testing.T) {
   148  	// Create a node and gets it computed class
   149  	n := testNode()
   150  	if err := n.ComputeClass(); err != nil {
   151  		t.Fatalf("ComputeClass() failed: %v", err)
   152  	}
   153  	if n.ComputedClass == "" {
   154  		t.Fatal("ComputeClass() didn't set computed class")
   155  	}
   156  	old := n.ComputedClass
   157  
   158  	// Modify a meta key and compute the class again.
   159  	n.Meta["pci-dss"] = "false"
   160  	if err := n.ComputeClass(); err != nil {
   161  		t.Fatalf("ComputeClass() failed: %v", err)
   162  	}
   163  	if n.ComputedClass == "" {
   164  		t.Fatal("ComputeClass() didn't set computed class")
   165  	}
   166  	if old == n.ComputedClass {
   167  		t.Fatal("ComputeClass() ignored meta change")
   168  	}
   169  	old = n.ComputedClass
   170  
   171  	// Add a unique meta key and compute the class again.
   172  	n.Meta["unique.foo"] = "ignore"
   173  	if err := n.ComputeClass(); err != nil {
   174  		t.Fatalf("ComputeClass() failed: %v", err)
   175  	}
   176  	if n.ComputedClass == "" {
   177  		t.Fatal("ComputeClass() didn't set computed class")
   178  	}
   179  	if old != n.ComputedClass {
   180  		t.Fatal("ComputeClass() didn't ignore unique meta key")
   181  	}
   182  }
   183  
   184  func TestNode_EscapedConstraints(t *testing.T) {
   185  	// Non-escaped constraints
   186  	ne1 := &Constraint{
   187  		LTarget: "${attr.kernel.name}",
   188  		RTarget: "linux",
   189  		Operand: "=",
   190  	}
   191  	ne2 := &Constraint{
   192  		LTarget: "${meta.key_foo}",
   193  		RTarget: "linux",
   194  		Operand: "<",
   195  	}
   196  	ne3 := &Constraint{
   197  		LTarget: "${node.dc}",
   198  		RTarget: "test",
   199  		Operand: "!=",
   200  	}
   201  
   202  	// Escaped constraints
   203  	e1 := &Constraint{
   204  		LTarget: "${attr.unique.kernel.name}",
   205  		RTarget: "linux",
   206  		Operand: "=",
   207  	}
   208  	e2 := &Constraint{
   209  		LTarget: "${meta.unique.key_foo}",
   210  		RTarget: "linux",
   211  		Operand: "<",
   212  	}
   213  	e3 := &Constraint{
   214  		LTarget: "${unique.node.id}",
   215  		RTarget: "test",
   216  		Operand: "!=",
   217  	}
   218  	constraints := []*Constraint{ne1, ne2, ne3, e1, e2, e3}
   219  	expected := []*Constraint{ne1, ne2, ne3}
   220  	if act := EscapedConstraints(constraints); reflect.DeepEqual(act, expected) {
   221  		t.Fatalf("EscapedConstraints(%v) returned %v; want %v", constraints, act, expected)
   222  	}
   223  }