github.com/adityamillind98/nomad@v0.11.8/scheduler/annotate_test.go (about) 1 package scheduler 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/hashicorp/nomad/nomad/structs" 8 ) 9 10 func TestAnnotateTaskGroup_Updates(t *testing.T) { 11 annotations := &structs.PlanAnnotations{ 12 DesiredTGUpdates: map[string]*structs.DesiredUpdates{ 13 "foo": { 14 Ignore: 1, 15 Place: 2, 16 Migrate: 3, 17 Stop: 4, 18 InPlaceUpdate: 5, 19 DestructiveUpdate: 6, 20 Canary: 7, 21 }, 22 }, 23 } 24 25 tgDiff := &structs.TaskGroupDiff{ 26 Type: structs.DiffTypeEdited, 27 Name: "foo", 28 } 29 expected := &structs.TaskGroupDiff{ 30 Type: structs.DiffTypeEdited, 31 Name: "foo", 32 Updates: map[string]uint64{ 33 UpdateTypeIgnore: 1, 34 UpdateTypeCreate: 2, 35 UpdateTypeMigrate: 3, 36 UpdateTypeDestroy: 4, 37 UpdateTypeInplaceUpdate: 5, 38 UpdateTypeDestructiveUpdate: 6, 39 UpdateTypeCanary: 7, 40 }, 41 } 42 43 if err := annotateTaskGroup(tgDiff, annotations); err != nil { 44 t.Fatalf("annotateTaskGroup(%#v, %#v) failed: %#v", tgDiff, annotations, err) 45 } 46 47 if !reflect.DeepEqual(tgDiff, expected) { 48 t.Fatalf("got %#v, want %#v", tgDiff, expected) 49 } 50 } 51 52 func TestAnnotateCountChange_NonEdited(t *testing.T) { 53 tg := &structs.TaskGroupDiff{} 54 tgOrig := &structs.TaskGroupDiff{} 55 annotateCountChange(tg) 56 if !reflect.DeepEqual(tgOrig, tg) { 57 t.Fatalf("annotateCountChange(%#v) should not have caused any annotation: %#v", tgOrig, tg) 58 } 59 } 60 61 func TestAnnotateCountChange(t *testing.T) { 62 up := &structs.FieldDiff{ 63 Type: structs.DiffTypeEdited, 64 Name: "Count", 65 Old: "1", 66 New: "3", 67 } 68 down := &structs.FieldDiff{ 69 Type: structs.DiffTypeEdited, 70 Name: "Count", 71 Old: "3", 72 New: "1", 73 } 74 tgUp := &structs.TaskGroupDiff{ 75 Type: structs.DiffTypeEdited, 76 Fields: []*structs.FieldDiff{up}, 77 } 78 tgDown := &structs.TaskGroupDiff{ 79 Type: structs.DiffTypeEdited, 80 Fields: []*structs.FieldDiff{down}, 81 } 82 83 // Test the up case 84 if err := annotateCountChange(tgUp); err != nil { 85 t.Fatalf("annotateCountChange(%#v) failed: %v", tgUp, err) 86 } 87 countDiff := tgUp.Fields[0] 88 if len(countDiff.Annotations) != 1 || countDiff.Annotations[0] != AnnotationForcesCreate { 89 t.Fatalf("incorrect annotation: %#v", tgUp) 90 } 91 92 // Test the down case 93 if err := annotateCountChange(tgDown); err != nil { 94 t.Fatalf("annotateCountChange(%#v) failed: %v", tgDown, err) 95 } 96 countDiff = tgDown.Fields[0] 97 if len(countDiff.Annotations) != 1 || countDiff.Annotations[0] != AnnotationForcesDestroy { 98 t.Fatalf("incorrect annotation: %#v", tgDown) 99 } 100 } 101 102 func TestAnnotateTask_NonEdited(t *testing.T) { 103 tgd := &structs.TaskGroupDiff{Type: structs.DiffTypeNone} 104 td := &structs.TaskDiff{Type: structs.DiffTypeNone} 105 tdOrig := &structs.TaskDiff{Type: structs.DiffTypeNone} 106 annotateTask(td, tgd) 107 if !reflect.DeepEqual(tdOrig, td) { 108 t.Fatalf("annotateTask(%#v) should not have caused any annotation: %#v", tdOrig, td) 109 } 110 } 111 112 func TestAnnotateTask(t *testing.T) { 113 cases := []struct { 114 Diff *structs.TaskDiff 115 Parent *structs.TaskGroupDiff 116 Desired string 117 }{ 118 { 119 Diff: &structs.TaskDiff{ 120 Type: structs.DiffTypeEdited, 121 Fields: []*structs.FieldDiff{ 122 { 123 Type: structs.DiffTypeEdited, 124 Name: "Driver", 125 Old: "docker", 126 New: "exec", 127 }, 128 }, 129 }, 130 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 131 Desired: AnnotationForcesDestructiveUpdate, 132 }, 133 { 134 Diff: &structs.TaskDiff{ 135 Type: structs.DiffTypeEdited, 136 Fields: []*structs.FieldDiff{ 137 { 138 Type: structs.DiffTypeEdited, 139 Name: "User", 140 Old: "alice", 141 New: "bob", 142 }, 143 }, 144 }, 145 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 146 Desired: AnnotationForcesDestructiveUpdate, 147 }, 148 { 149 Diff: &structs.TaskDiff{ 150 Type: structs.DiffTypeEdited, 151 Fields: []*structs.FieldDiff{ 152 { 153 Type: structs.DiffTypeAdded, 154 Name: "Env[foo]", 155 Old: "foo", 156 New: "bar", 157 }, 158 }, 159 }, 160 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 161 Desired: AnnotationForcesDestructiveUpdate, 162 }, 163 { 164 Diff: &structs.TaskDiff{ 165 Type: structs.DiffTypeEdited, 166 Fields: []*structs.FieldDiff{ 167 { 168 Type: structs.DiffTypeAdded, 169 Name: "Meta[foo]", 170 Old: "foo", 171 New: "bar", 172 }, 173 }, 174 }, 175 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 176 Desired: AnnotationForcesDestructiveUpdate, 177 }, 178 { 179 Diff: &structs.TaskDiff{ 180 Type: structs.DiffTypeEdited, 181 Objects: []*structs.ObjectDiff{ 182 { 183 Type: structs.DiffTypeAdded, 184 Name: "Artifact", 185 Fields: []*structs.FieldDiff{ 186 { 187 Type: structs.DiffTypeAdded, 188 Name: "GetterOptions[bam]", 189 Old: "", 190 New: "baz", 191 }, 192 { 193 Type: structs.DiffTypeAdded, 194 Name: "GetterSource", 195 Old: "", 196 New: "bam", 197 }, 198 { 199 Type: structs.DiffTypeAdded, 200 Name: "RelativeDest", 201 Old: "", 202 New: "bam", 203 }, 204 }, 205 }, 206 }, 207 }, 208 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 209 Desired: AnnotationForcesDestructiveUpdate, 210 }, 211 { 212 Diff: &structs.TaskDiff{ 213 Type: structs.DiffTypeEdited, 214 Objects: []*structs.ObjectDiff{ 215 { 216 Type: structs.DiffTypeEdited, 217 Name: "Resources", 218 Fields: []*structs.FieldDiff{ 219 { 220 Type: structs.DiffTypeEdited, 221 Name: "CPU", 222 Old: "100", 223 New: "200", 224 }, 225 { 226 Type: structs.DiffTypeEdited, 227 Name: "DiskMB", 228 Old: "100", 229 New: "200", 230 }, 231 { 232 Type: structs.DiffTypeEdited, 233 Name: "MemoryMB", 234 Old: "100", 235 New: "200", 236 }, 237 }, 238 }, 239 }, 240 }, 241 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 242 Desired: AnnotationForcesDestructiveUpdate, 243 }, 244 { 245 Diff: &structs.TaskDiff{ 246 Type: structs.DiffTypeEdited, 247 Objects: []*structs.ObjectDiff{ 248 { 249 Type: structs.DiffTypeEdited, 250 Name: "Config", 251 Fields: []*structs.FieldDiff{ 252 { 253 Type: structs.DiffTypeEdited, 254 Name: "bam[1]", 255 Old: "b", 256 New: "c", 257 }, 258 }, 259 }, 260 }, 261 }, 262 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 263 Desired: AnnotationForcesDestructiveUpdate, 264 }, 265 { 266 Diff: &structs.TaskDiff{ 267 Type: structs.DiffTypeEdited, 268 Objects: []*structs.ObjectDiff{ 269 { 270 Type: structs.DiffTypeAdded, 271 Name: "Constraint", 272 Fields: []*structs.FieldDiff{ 273 { 274 Type: structs.DiffTypeAdded, 275 Name: "LTarget", 276 Old: "", 277 New: "baz", 278 }, 279 { 280 Type: structs.DiffTypeAdded, 281 Name: "Operand", 282 Old: "", 283 New: "baz", 284 }, 285 { 286 Type: structs.DiffTypeAdded, 287 Name: "RTarget", 288 Old: "", 289 New: "baz", 290 }, 291 }, 292 }, 293 }, 294 }, 295 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 296 Desired: AnnotationForcesInplaceUpdate, 297 }, 298 { 299 Diff: &structs.TaskDiff{ 300 Type: structs.DiffTypeEdited, 301 Objects: []*structs.ObjectDiff{ 302 { 303 Type: structs.DiffTypeAdded, 304 Name: "LogConfig", 305 Fields: []*structs.FieldDiff{ 306 { 307 Type: structs.DiffTypeAdded, 308 Name: "MaxFileSizeMB", 309 Old: "", 310 New: "10", 311 }, 312 { 313 Type: structs.DiffTypeAdded, 314 Name: "MaxFiles", 315 Old: "", 316 New: "1", 317 }, 318 }, 319 }, 320 }, 321 }, 322 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 323 Desired: AnnotationForcesInplaceUpdate, 324 }, 325 { 326 Diff: &structs.TaskDiff{ 327 Type: structs.DiffTypeEdited, 328 Objects: []*structs.ObjectDiff{ 329 { 330 Type: structs.DiffTypeEdited, 331 Name: "Service", 332 Fields: []*structs.FieldDiff{ 333 { 334 Type: structs.DiffTypeEdited, 335 Name: "PortLabel", 336 Old: "baz", 337 New: "baz2", 338 }, 339 }, 340 }, 341 }, 342 }, 343 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 344 Desired: AnnotationForcesInplaceUpdate, 345 }, 346 { 347 Diff: &structs.TaskDiff{ 348 Type: structs.DiffTypeEdited, 349 Fields: []*structs.FieldDiff{ 350 { 351 Type: structs.DiffTypeEdited, 352 Name: "KillTimeout", 353 Old: "200", 354 New: "2000000", 355 }, 356 }, 357 }, 358 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 359 Desired: AnnotationForcesInplaceUpdate, 360 }, 361 // Task deleted new parent 362 { 363 Diff: &structs.TaskDiff{ 364 Type: structs.DiffTypeDeleted, 365 Fields: []*structs.FieldDiff{ 366 { 367 Type: structs.DiffTypeAdded, 368 Name: "Driver", 369 Old: "", 370 New: "exec", 371 }, 372 }, 373 }, 374 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeAdded}, 375 Desired: AnnotationForcesDestroy, 376 }, 377 // Task Added new parent 378 { 379 Diff: &structs.TaskDiff{ 380 Type: structs.DiffTypeAdded, 381 Fields: []*structs.FieldDiff{ 382 { 383 Type: structs.DiffTypeAdded, 384 Name: "Driver", 385 Old: "", 386 New: "exec", 387 }, 388 }, 389 }, 390 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeAdded}, 391 Desired: AnnotationForcesCreate, 392 }, 393 // Task deleted existing parent 394 { 395 Diff: &structs.TaskDiff{ 396 Type: structs.DiffTypeDeleted, 397 Fields: []*structs.FieldDiff{ 398 { 399 Type: structs.DiffTypeAdded, 400 Name: "Driver", 401 Old: "", 402 New: "exec", 403 }, 404 }, 405 }, 406 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 407 Desired: AnnotationForcesDestructiveUpdate, 408 }, 409 // Task Added existing parent 410 { 411 Diff: &structs.TaskDiff{ 412 Type: structs.DiffTypeAdded, 413 Fields: []*structs.FieldDiff{ 414 { 415 Type: structs.DiffTypeAdded, 416 Name: "Driver", 417 Old: "", 418 New: "exec", 419 }, 420 }, 421 }, 422 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 423 Desired: AnnotationForcesDestructiveUpdate, 424 }, 425 } 426 427 for i, c := range cases { 428 annotateTask(c.Diff, c.Parent) 429 if len(c.Diff.Annotations) != 1 || c.Diff.Annotations[0] != c.Desired { 430 t.Fatalf("case %d not properly annotated; got %s, want %s", i+1, c.Diff.Annotations[0], c.Desired) 431 } 432 } 433 }