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  }