github.com/djenriquez/nomad-1@v0.8.1/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: "IOPS", 234 Old: "100", 235 New: "200", 236 }, 237 { 238 Type: structs.DiffTypeEdited, 239 Name: "MemoryMB", 240 Old: "100", 241 New: "200", 242 }, 243 }, 244 }, 245 }, 246 }, 247 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 248 Desired: AnnotationForcesDestructiveUpdate, 249 }, 250 { 251 Diff: &structs.TaskDiff{ 252 Type: structs.DiffTypeEdited, 253 Objects: []*structs.ObjectDiff{ 254 { 255 Type: structs.DiffTypeEdited, 256 Name: "Config", 257 Fields: []*structs.FieldDiff{ 258 { 259 Type: structs.DiffTypeEdited, 260 Name: "bam[1]", 261 Old: "b", 262 New: "c", 263 }, 264 }, 265 }, 266 }, 267 }, 268 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 269 Desired: AnnotationForcesDestructiveUpdate, 270 }, 271 { 272 Diff: &structs.TaskDiff{ 273 Type: structs.DiffTypeEdited, 274 Objects: []*structs.ObjectDiff{ 275 { 276 Type: structs.DiffTypeAdded, 277 Name: "Constraint", 278 Fields: []*structs.FieldDiff{ 279 { 280 Type: structs.DiffTypeAdded, 281 Name: "LTarget", 282 Old: "", 283 New: "baz", 284 }, 285 { 286 Type: structs.DiffTypeAdded, 287 Name: "Operand", 288 Old: "", 289 New: "baz", 290 }, 291 { 292 Type: structs.DiffTypeAdded, 293 Name: "RTarget", 294 Old: "", 295 New: "baz", 296 }, 297 }, 298 }, 299 }, 300 }, 301 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 302 Desired: AnnotationForcesInplaceUpdate, 303 }, 304 { 305 Diff: &structs.TaskDiff{ 306 Type: structs.DiffTypeEdited, 307 Objects: []*structs.ObjectDiff{ 308 { 309 Type: structs.DiffTypeAdded, 310 Name: "LogConfig", 311 Fields: []*structs.FieldDiff{ 312 { 313 Type: structs.DiffTypeAdded, 314 Name: "MaxFileSizeMB", 315 Old: "", 316 New: "10", 317 }, 318 { 319 Type: structs.DiffTypeAdded, 320 Name: "MaxFiles", 321 Old: "", 322 New: "1", 323 }, 324 }, 325 }, 326 }, 327 }, 328 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 329 Desired: AnnotationForcesInplaceUpdate, 330 }, 331 { 332 Diff: &structs.TaskDiff{ 333 Type: structs.DiffTypeEdited, 334 Objects: []*structs.ObjectDiff{ 335 { 336 Type: structs.DiffTypeEdited, 337 Name: "Service", 338 Fields: []*structs.FieldDiff{ 339 { 340 Type: structs.DiffTypeEdited, 341 Name: "PortLabel", 342 Old: "baz", 343 New: "baz2", 344 }, 345 }, 346 }, 347 }, 348 }, 349 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 350 Desired: AnnotationForcesInplaceUpdate, 351 }, 352 { 353 Diff: &structs.TaskDiff{ 354 Type: structs.DiffTypeEdited, 355 Fields: []*structs.FieldDiff{ 356 { 357 Type: structs.DiffTypeEdited, 358 Name: "KillTimeout", 359 Old: "200", 360 New: "2000000", 361 }, 362 }, 363 }, 364 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 365 Desired: AnnotationForcesInplaceUpdate, 366 }, 367 // Task deleted new parent 368 { 369 Diff: &structs.TaskDiff{ 370 Type: structs.DiffTypeDeleted, 371 Fields: []*structs.FieldDiff{ 372 { 373 Type: structs.DiffTypeAdded, 374 Name: "Driver", 375 Old: "", 376 New: "exec", 377 }, 378 }, 379 }, 380 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeAdded}, 381 Desired: AnnotationForcesDestroy, 382 }, 383 // Task Added new parent 384 { 385 Diff: &structs.TaskDiff{ 386 Type: structs.DiffTypeAdded, 387 Fields: []*structs.FieldDiff{ 388 { 389 Type: structs.DiffTypeAdded, 390 Name: "Driver", 391 Old: "", 392 New: "exec", 393 }, 394 }, 395 }, 396 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeAdded}, 397 Desired: AnnotationForcesCreate, 398 }, 399 // Task deleted existing parent 400 { 401 Diff: &structs.TaskDiff{ 402 Type: structs.DiffTypeDeleted, 403 Fields: []*structs.FieldDiff{ 404 { 405 Type: structs.DiffTypeAdded, 406 Name: "Driver", 407 Old: "", 408 New: "exec", 409 }, 410 }, 411 }, 412 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 413 Desired: AnnotationForcesDestructiveUpdate, 414 }, 415 // Task Added existing parent 416 { 417 Diff: &structs.TaskDiff{ 418 Type: structs.DiffTypeAdded, 419 Fields: []*structs.FieldDiff{ 420 { 421 Type: structs.DiffTypeAdded, 422 Name: "Driver", 423 Old: "", 424 New: "exec", 425 }, 426 }, 427 }, 428 Parent: &structs.TaskGroupDiff{Type: structs.DiffTypeEdited}, 429 Desired: AnnotationForcesDestructiveUpdate, 430 }, 431 } 432 433 for i, c := range cases { 434 annotateTask(c.Diff, c.Parent) 435 if len(c.Diff.Annotations) != 1 || c.Diff.Annotations[0] != c.Desired { 436 t.Fatalf("case %d not properly annotated; got %s, want %s", i+1, c.Diff.Annotations[0], c.Desired) 437 } 438 } 439 }