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 }