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