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