github.com/hernad/nomad@v1.6.112/nomad/structs/testing.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package structs 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/hernad/nomad/helper/uuid" 11 psstructs "github.com/hernad/nomad/plugins/shared/structs" 12 ) 13 14 // NodeResourcesToAllocatedResources converts a node resources to an allocated 15 // resources. The task name used is "web" and network is omitted. This is 16 // useful when trying to make an allocation fill an entire node. 17 func NodeResourcesToAllocatedResources(n *NodeResources) *AllocatedResources { 18 if n == nil { 19 return nil 20 } 21 22 return &AllocatedResources{ 23 Tasks: map[string]*AllocatedTaskResources{ 24 "web": { 25 Cpu: AllocatedCpuResources{ 26 CpuShares: n.Cpu.CpuShares, 27 }, 28 Memory: AllocatedMemoryResources{ 29 MemoryMB: n.Memory.MemoryMB, 30 }, 31 }, 32 }, 33 Shared: AllocatedSharedResources{ 34 DiskMB: n.Disk.DiskMB, 35 }, 36 } 37 } 38 39 func MockNode() *Node { 40 node := &Node{ 41 ID: uuid.Generate(), 42 SecretID: uuid.Generate(), 43 Datacenter: "dc1", 44 Name: "foobar", 45 Attributes: map[string]string{ 46 "kernel.name": "linux", 47 "arch": "x86", 48 "nomad.version": "1.0.0", 49 "driver.exec": "1", 50 "driver.mock_driver": "1", 51 }, 52 NodeResources: &NodeResources{ 53 Cpu: NodeCpuResources{ 54 CpuShares: 4000, 55 }, 56 Memory: NodeMemoryResources{ 57 MemoryMB: 8192, 58 }, 59 Disk: NodeDiskResources{ 60 DiskMB: 100 * 1024, 61 }, 62 Networks: []*NetworkResource{ 63 { 64 Device: "eth0", 65 CIDR: "192.168.0.100/32", 66 MBits: 1000, 67 }, 68 }, 69 }, 70 ReservedResources: &NodeReservedResources{ 71 Cpu: NodeReservedCpuResources{ 72 CpuShares: 100, 73 }, 74 Memory: NodeReservedMemoryResources{ 75 MemoryMB: 256, 76 }, 77 Disk: NodeReservedDiskResources{ 78 DiskMB: 4 * 1024, 79 }, 80 Networks: NodeReservedNetworkResources{ 81 ReservedHostPorts: "22", 82 }, 83 }, 84 Links: map[string]string{ 85 "consul": "foobar.dc1", 86 }, 87 Meta: map[string]string{ 88 "pci-dss": "true", 89 "database": "mysql", 90 "version": "5.6", 91 }, 92 NodeClass: "linux-medium-pci", 93 Status: NodeStatusReady, 94 SchedulingEligibility: NodeSchedulingEligible, 95 } 96 err := node.ComputeClass() 97 if err != nil { 98 panic(fmt.Sprintf("failed to compute node class: %v", err)) 99 } 100 return node 101 } 102 103 // MockNvidiaNode returns a node with two instances of an Nvidia GPU 104 func MockNvidiaNode() *Node { 105 n := MockNode() 106 n.NodeResources.Devices = []*NodeDeviceResource{ 107 { 108 Type: "gpu", 109 Vendor: "nvidia", 110 Name: "1080ti", 111 Attributes: map[string]*psstructs.Attribute{ 112 "memory": psstructs.NewIntAttribute(11, psstructs.UnitGiB), 113 "cuda_cores": psstructs.NewIntAttribute(3584, ""), 114 "graphics_clock": psstructs.NewIntAttribute(1480, psstructs.UnitMHz), 115 "memory_bandwidth": psstructs.NewIntAttribute(11, psstructs.UnitGBPerS), 116 }, 117 Instances: []*NodeDevice{ 118 { 119 ID: uuid.Generate(), 120 Healthy: true, 121 }, 122 { 123 ID: uuid.Generate(), 124 Healthy: true, 125 }, 126 }, 127 }, 128 } 129 err := n.ComputeClass() 130 if err != nil { 131 panic(fmt.Sprintf("failed to compute node class: %v", err)) 132 } 133 return n 134 } 135 136 func MockJob() *Job { 137 job := &Job{ 138 Region: "global", 139 ID: fmt.Sprintf("mock-service-%s", uuid.Generate()), 140 Name: "my-job", 141 Namespace: DefaultNamespace, 142 Type: JobTypeService, 143 Priority: 50, 144 AllAtOnce: false, 145 Datacenters: []string{"dc1"}, 146 Constraints: []*Constraint{ 147 { 148 LTarget: "${attr.kernel.name}", 149 RTarget: "linux", 150 Operand: "=", 151 }, 152 }, 153 TaskGroups: []*TaskGroup{ 154 { 155 Name: "web", 156 Count: 10, 157 EphemeralDisk: &EphemeralDisk{ 158 SizeMB: 150, 159 }, 160 RestartPolicy: &RestartPolicy{ 161 Attempts: 3, 162 Interval: 10 * time.Minute, 163 Delay: 1 * time.Minute, 164 Mode: RestartPolicyModeDelay, 165 }, 166 ReschedulePolicy: &ReschedulePolicy{ 167 Attempts: 2, 168 Interval: 10 * time.Minute, 169 Delay: 5 * time.Second, 170 DelayFunction: "constant", 171 }, 172 Migrate: DefaultMigrateStrategy(), 173 Tasks: []*Task{ 174 { 175 Name: "web", 176 Driver: "exec", 177 Config: map[string]interface{}{ 178 "command": "/bin/date", 179 }, 180 Env: map[string]string{ 181 "FOO": "bar", 182 }, 183 Services: []*Service{ 184 { 185 Name: "${TASK}-frontend", 186 PortLabel: "http", 187 Tags: []string{"pci:${meta.pci-dss}", "datacenter:${node.datacenter}"}, 188 Checks: []*ServiceCheck{ 189 { 190 Name: "check-table", 191 Type: ServiceCheckScript, 192 Command: "/usr/local/check-table-${meta.database}", 193 Args: []string{"${meta.version}"}, 194 Interval: 30 * time.Second, 195 Timeout: 5 * time.Second, 196 }, 197 }, 198 }, 199 { 200 Name: "${TASK}-admin", 201 PortLabel: "admin", 202 }, 203 }, 204 LogConfig: DefaultLogConfig(), 205 Resources: &Resources{ 206 CPU: 500, 207 MemoryMB: 256, 208 Networks: []*NetworkResource{ 209 { 210 MBits: 50, 211 DynamicPorts: []Port{ 212 {Label: "http"}, 213 {Label: "admin"}, 214 }, 215 }, 216 }, 217 }, 218 Meta: map[string]string{ 219 "foo": "bar", 220 }, 221 }, 222 }, 223 Meta: map[string]string{ 224 "elb_check_type": "http", 225 "elb_check_interval": "30s", 226 "elb_check_min": "3", 227 }, 228 }, 229 }, 230 Meta: map[string]string{ 231 "owner": "armon", 232 }, 233 Status: JobStatusPending, 234 Version: 0, 235 CreateIndex: 42, 236 ModifyIndex: 99, 237 JobModifyIndex: 99, 238 } 239 job.Canonicalize() 240 return job 241 } 242 243 func MockAlloc() *Allocation { 244 alloc := &Allocation{ 245 ID: uuid.Generate(), 246 EvalID: uuid.Generate(), 247 NodeID: "12345678-abcd-efab-cdef-123456789abc", 248 Namespace: DefaultNamespace, 249 TaskGroup: "web", 250 AllocatedResources: &AllocatedResources{ 251 Tasks: map[string]*AllocatedTaskResources{ 252 "web": { 253 Cpu: AllocatedCpuResources{ 254 CpuShares: 500, 255 }, 256 Memory: AllocatedMemoryResources{ 257 MemoryMB: 256, 258 }, 259 Networks: []*NetworkResource{ 260 { 261 Device: "eth0", 262 IP: "192.168.0.100", 263 ReservedPorts: []Port{{Label: "admin", Value: 5000}}, 264 MBits: 50, 265 DynamicPorts: []Port{{Label: "http", Value: 9876}}, 266 }, 267 }, 268 }, 269 }, 270 Shared: AllocatedSharedResources{ 271 DiskMB: 150, 272 }, 273 }, 274 Job: MockJob(), 275 DesiredStatus: AllocDesiredStatusRun, 276 ClientStatus: AllocClientStatusPending, 277 } 278 alloc.JobID = alloc.Job.ID 279 return alloc 280 }