github.com/hernad/nomad@v1.6.112/nomad/structs/node_pool_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package structs 5 6 import ( 7 "strings" 8 "testing" 9 10 "github.com/hernad/nomad/ci" 11 "github.com/hernad/nomad/helper/pointer" 12 "github.com/shoenig/test/must" 13 ) 14 15 func TestNodePool_Copy(t *testing.T) { 16 ci.Parallel(t) 17 18 pool := &NodePool{ 19 Name: "original", 20 Description: "original node pool", 21 Meta: map[string]string{"original": "true"}, 22 SchedulerConfiguration: &NodePoolSchedulerConfiguration{ 23 SchedulerAlgorithm: SchedulerAlgorithmSpread, 24 MemoryOversubscriptionEnabled: pointer.Of(false), 25 }, 26 } 27 poolCopy := pool.Copy() 28 poolCopy.Name = "copy" 29 poolCopy.Description = "copy of original pool" 30 poolCopy.Meta["original"] = "false" 31 poolCopy.Meta["new_key"] = "true" 32 poolCopy.SchedulerConfiguration.SchedulerAlgorithm = SchedulerAlgorithmBinpack 33 poolCopy.SchedulerConfiguration.MemoryOversubscriptionEnabled = pointer.Of(true) 34 35 must.NotEq(t, pool, poolCopy) 36 must.NotEq(t, pool.Meta, poolCopy.Meta) 37 must.NotEq(t, pool.SchedulerConfiguration, poolCopy.SchedulerConfiguration) 38 } 39 40 func TestNodePool_Validate(t *testing.T) { 41 ci.Parallel(t) 42 43 testCases := []struct { 44 name string 45 pool *NodePool 46 expectedErr string 47 }{ 48 { 49 name: "valid pool", 50 pool: &NodePool{ 51 Name: "valid", 52 Description: "ok", 53 }, 54 }, 55 { 56 name: "invalid pool name character", 57 pool: &NodePool{ 58 Name: "not-valid-😢", 59 }, 60 expectedErr: "invalid name", 61 }, 62 { 63 name: "missing pool name", 64 pool: &NodePool{ 65 Name: "", 66 }, 67 expectedErr: "invalid name", 68 }, 69 { 70 name: "invalid pool description", 71 pool: &NodePool{ 72 Name: "valid", 73 Description: strings.Repeat("a", 300), 74 }, 75 expectedErr: "description longer", 76 }, 77 } 78 79 for _, tc := range testCases { 80 t.Run(tc.name, func(t *testing.T) { 81 err := tc.pool.Validate() 82 83 if tc.expectedErr != "" { 84 must.ErrorContains(t, err, tc.expectedErr) 85 } else { 86 must.NoError(t, err) 87 } 88 }) 89 } 90 } 91 92 func TestNodePool_IsBuiltIn(t *testing.T) { 93 ci.Parallel(t) 94 95 testCases := []struct { 96 name string 97 pool *NodePool 98 builtIn bool 99 }{ 100 { 101 name: "all", 102 pool: &NodePool{ 103 Name: NodePoolAll, 104 }, 105 builtIn: true, 106 }, 107 { 108 name: "default", 109 pool: &NodePool{ 110 Name: NodePoolDefault, 111 }, 112 builtIn: true, 113 }, 114 { 115 name: "not built-in", 116 pool: &NodePool{ 117 Name: "not-built-in", 118 }, 119 builtIn: false, 120 }, 121 } 122 123 for _, tc := range testCases { 124 t.Run(tc.name, func(t *testing.T) { 125 got := tc.pool.IsBuiltIn() 126 must.Eq(t, tc.builtIn, got) 127 }) 128 } 129 } 130 131 func TestNodePool_MemoryOversubscriptionEnabled(t *testing.T) { 132 ci.Parallel(t) 133 134 testCases := []struct { 135 name string 136 pool *NodePool 137 global *SchedulerConfiguration 138 expected bool 139 }{ 140 { 141 name: "global used if pool is nil", 142 pool: nil, 143 global: &SchedulerConfiguration{ 144 MemoryOversubscriptionEnabled: true, 145 }, 146 expected: true, 147 }, 148 { 149 name: "global used if pool doesn't have scheduler config", 150 pool: &NodePool{}, 151 global: &SchedulerConfiguration{ 152 MemoryOversubscriptionEnabled: true, 153 }, 154 expected: true, 155 }, 156 { 157 name: "global used if pool doesn't specify memory oversub", 158 pool: &NodePool{ 159 SchedulerConfiguration: &NodePoolSchedulerConfiguration{}, 160 }, 161 global: &SchedulerConfiguration{ 162 MemoryOversubscriptionEnabled: true, 163 }, 164 expected: true, 165 }, 166 { 167 name: "pool overrides global if it defines memory oversub", 168 pool: &NodePool{ 169 SchedulerConfiguration: &NodePoolSchedulerConfiguration{ 170 MemoryOversubscriptionEnabled: pointer.Of(false), 171 }, 172 }, 173 global: &SchedulerConfiguration{ 174 MemoryOversubscriptionEnabled: true, 175 }, 176 expected: false, 177 }, 178 { 179 name: "pool used if global is nil", 180 pool: &NodePool{ 181 SchedulerConfiguration: &NodePoolSchedulerConfiguration{ 182 MemoryOversubscriptionEnabled: pointer.Of(true), 183 }, 184 }, 185 global: nil, 186 expected: true, 187 }, 188 } 189 190 for _, tc := range testCases { 191 t.Run(tc.name, func(t *testing.T) { 192 got := tc.pool.MemoryOversubscriptionEnabled(tc.global) 193 must.Eq(t, got, tc.expected) 194 }) 195 } 196 }