github.com/taylorchu/nomad@v0.5.3-rc1.0.20170407200202-db11e7dd7b55/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  		{
   351  			Diff: &structs.TaskDiff{
   352  				Type: structs.DiffTypeEdited,
   353  				Fields: []*structs.FieldDiff{
   354  					{
   355  						Type: structs.DiffTypeEdited,
   356  						Name: "KillTimeout",
   357  						Old:  "200",
   358  						New:  "2000000",
   359  					},
   360  				},
   361  			},
   362  			Parent:  &structs.TaskGroupDiff{Type: structs.DiffTypeEdited},
   363  			Desired: AnnotationForcesInplaceUpdate,
   364  		},
   365  		// Task deleted new parent
   366  		{
   367  			Diff: &structs.TaskDiff{
   368  				Type: structs.DiffTypeDeleted,
   369  				Fields: []*structs.FieldDiff{
   370  					{
   371  						Type: structs.DiffTypeAdded,
   372  						Name: "Driver",
   373  						Old:  "",
   374  						New:  "exec",
   375  					},
   376  				},
   377  			},
   378  			Parent:  &structs.TaskGroupDiff{Type: structs.DiffTypeAdded},
   379  			Desired: AnnotationForcesDestroy,
   380  		},
   381  		// Task Added new parent
   382  		{
   383  			Diff: &structs.TaskDiff{
   384  				Type: structs.DiffTypeAdded,
   385  				Fields: []*structs.FieldDiff{
   386  					{
   387  						Type: structs.DiffTypeAdded,
   388  						Name: "Driver",
   389  						Old:  "",
   390  						New:  "exec",
   391  					},
   392  				},
   393  			},
   394  			Parent:  &structs.TaskGroupDiff{Type: structs.DiffTypeAdded},
   395  			Desired: AnnotationForcesCreate,
   396  		},
   397  		// Task deleted existing parent
   398  		{
   399  			Diff: &structs.TaskDiff{
   400  				Type: structs.DiffTypeDeleted,
   401  				Fields: []*structs.FieldDiff{
   402  					{
   403  						Type: structs.DiffTypeAdded,
   404  						Name: "Driver",
   405  						Old:  "",
   406  						New:  "exec",
   407  					},
   408  				},
   409  			},
   410  			Parent:  &structs.TaskGroupDiff{Type: structs.DiffTypeEdited},
   411  			Desired: AnnotationForcesDestructiveUpdate,
   412  		},
   413  		// Task Added existing parent
   414  		{
   415  			Diff: &structs.TaskDiff{
   416  				Type: structs.DiffTypeAdded,
   417  				Fields: []*structs.FieldDiff{
   418  					{
   419  						Type: structs.DiffTypeAdded,
   420  						Name: "Driver",
   421  						Old:  "",
   422  						New:  "exec",
   423  					},
   424  				},
   425  			},
   426  			Parent:  &structs.TaskGroupDiff{Type: structs.DiffTypeEdited},
   427  			Desired: AnnotationForcesDestructiveUpdate,
   428  		},
   429  	}
   430  
   431  	for i, c := range cases {
   432  		annotateTask(c.Diff, c.Parent)
   433  		if len(c.Diff.Annotations) != 1 || c.Diff.Annotations[0] != c.Desired {
   434  			t.Fatalf("case %d not properly annotated; got %s, want %s", i+1, c.Diff.Annotations[0], c.Desired)
   435  		}
   436  	}
   437  }