b3ea68948b
Go 1.19 will forecefully format all your doc strings. To get this out of the way, here is one big commit with all the changes gofmt wants to make.
260 lines
6.1 KiB
Go
260 lines
6.1 KiB
Go
package structs
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/nomad/ci"
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
psstructs "github.com/hashicorp/nomad/plugins/shared/structs"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TODO Test
|
|
func testNode() *Node {
|
|
return &Node{
|
|
ID: uuid.Generate(),
|
|
Datacenter: "dc1",
|
|
Name: "foobar",
|
|
Attributes: map[string]string{
|
|
"kernel.name": "linux",
|
|
"arch": "x86",
|
|
"version": "0.1.0",
|
|
"driver.exec": "1",
|
|
},
|
|
NodeResources: &NodeResources{
|
|
Cpu: NodeCpuResources{
|
|
CpuShares: 4000,
|
|
},
|
|
Memory: NodeMemoryResources{
|
|
MemoryMB: 8192,
|
|
},
|
|
Disk: NodeDiskResources{
|
|
DiskMB: 100 * 1024,
|
|
},
|
|
Networks: []*NetworkResource{
|
|
{
|
|
Device: "eth0",
|
|
CIDR: "192.168.0.100/32",
|
|
IP: "192.168.0.100",
|
|
MBits: 1000,
|
|
},
|
|
},
|
|
},
|
|
Links: map[string]string{
|
|
"consul": "foobar.dc1",
|
|
},
|
|
Meta: map[string]string{
|
|
"pci-dss": "true",
|
|
},
|
|
NodeClass: "linux-medium-pci",
|
|
Status: NodeStatusReady,
|
|
}
|
|
}
|
|
|
|
func TestNode_ComputedClass(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
require := require.New(t)
|
|
|
|
// Create a node and gets it computed class
|
|
n := testNode()
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEmpty(n.ComputedClass)
|
|
old := n.ComputedClass
|
|
|
|
// Compute again to ensure determinism
|
|
require.NoError(n.ComputeClass())
|
|
require.Equal(n.ComputedClass, old)
|
|
|
|
// Modify a field and compute the class again.
|
|
n.Datacenter = "New DC"
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEqual(n.ComputedClass, old)
|
|
old = n.ComputedClass
|
|
|
|
// Add a device
|
|
n.NodeResources.Devices = append(n.NodeResources.Devices, &NodeDeviceResource{
|
|
Vendor: "foo",
|
|
Type: "gpu",
|
|
Name: "bam",
|
|
})
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEqual(n.ComputedClass, old)
|
|
}
|
|
|
|
func TestNode_ComputedClass_Ignore(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
require := require.New(t)
|
|
|
|
// Create a node and gets it computed class
|
|
n := testNode()
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEmpty(n.ComputedClass)
|
|
old := n.ComputedClass
|
|
|
|
// Modify an ignored field and compute the class again.
|
|
n.ID = "New ID"
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEmpty(n.ComputedClass)
|
|
require.Equal(n.ComputedClass, old)
|
|
|
|
}
|
|
|
|
func TestNode_ComputedClass_Device_Attr(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
require := require.New(t)
|
|
|
|
// Create a node and gets it computed class
|
|
n := testNode()
|
|
d := &NodeDeviceResource{
|
|
Vendor: "foo",
|
|
Type: "gpu",
|
|
Name: "bam",
|
|
Attributes: map[string]*psstructs.Attribute{
|
|
"foo": psstructs.NewBoolAttribute(true),
|
|
},
|
|
}
|
|
n.NodeResources.Devices = append(n.NodeResources.Devices, d)
|
|
require.NoError(n.ComputeClass())
|
|
require.NotEmpty(n.ComputedClass)
|
|
old := n.ComputedClass
|
|
|
|
// Update the attributes to be have a unique value
|
|
d.Attributes["unique.bar"] = psstructs.NewBoolAttribute(false)
|
|
require.NoError(n.ComputeClass())
|
|
require.Equal(n.ComputedClass, old)
|
|
}
|
|
|
|
func TestNode_ComputedClass_Attr(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
// Create a node and gets it computed class
|
|
n := testNode()
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
old := n.ComputedClass
|
|
|
|
// Add a unique addr and compute the class again
|
|
n.Attributes["unique.foo"] = "bar"
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if old != n.ComputedClass {
|
|
t.Fatal("ComputeClass() didn't ignore unique attr suffix")
|
|
}
|
|
|
|
// Modify an attribute and compute the class again.
|
|
n.Attributes["version"] = "New Version"
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
if old == n.ComputedClass {
|
|
t.Fatal("ComputeClass() ignored attribute change")
|
|
}
|
|
|
|
// Remove and attribute and compute the class again.
|
|
old = n.ComputedClass
|
|
delete(n.Attributes, "driver.exec")
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputedClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
if old == n.ComputedClass {
|
|
t.Fatalf("ComputedClass() ignored removal of attribute key")
|
|
}
|
|
}
|
|
|
|
func TestNode_ComputedClass_Meta(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
// Create a node and gets it computed class
|
|
n := testNode()
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
old := n.ComputedClass
|
|
|
|
// Modify a meta key and compute the class again.
|
|
n.Meta["pci-dss"] = "false"
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
if old == n.ComputedClass {
|
|
t.Fatal("ComputeClass() ignored meta change")
|
|
}
|
|
old = n.ComputedClass
|
|
|
|
// Add a unique meta key and compute the class again.
|
|
n.Meta["unique.foo"] = "ignore"
|
|
if err := n.ComputeClass(); err != nil {
|
|
t.Fatalf("ComputeClass() failed: %v", err)
|
|
}
|
|
if n.ComputedClass == "" {
|
|
t.Fatal("ComputeClass() didn't set computed class")
|
|
}
|
|
if old != n.ComputedClass {
|
|
t.Fatal("ComputeClass() didn't ignore unique meta key")
|
|
}
|
|
}
|
|
|
|
func TestNode_EscapedConstraints(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
// Non-escaped constraints
|
|
ne1 := &Constraint{
|
|
LTarget: "${attr.kernel.name}",
|
|
RTarget: "linux",
|
|
Operand: "=",
|
|
}
|
|
ne2 := &Constraint{
|
|
LTarget: "${meta.key_foo}",
|
|
RTarget: "linux",
|
|
Operand: "<",
|
|
}
|
|
ne3 := &Constraint{
|
|
LTarget: "${node.dc}",
|
|
RTarget: "test",
|
|
Operand: "!=",
|
|
}
|
|
|
|
// Escaped constraints
|
|
e1 := &Constraint{
|
|
LTarget: "${attr.unique.kernel.name}",
|
|
RTarget: "linux",
|
|
Operand: "=",
|
|
}
|
|
e2 := &Constraint{
|
|
LTarget: "${meta.unique.key_foo}",
|
|
RTarget: "linux",
|
|
Operand: "<",
|
|
}
|
|
e3 := &Constraint{
|
|
LTarget: "${unique.node.id}",
|
|
RTarget: "test",
|
|
Operand: "!=",
|
|
}
|
|
constraints := []*Constraint{ne1, ne2, ne3, e1, e2, e3}
|
|
expected := []*Constraint{ne1, ne2, ne3}
|
|
if act := EscapedConstraints(constraints); reflect.DeepEqual(act, expected) {
|
|
t.Fatalf("EscapedConstraints(%v) returned %v; want %v", constraints, act, expected)
|
|
}
|
|
}
|