diff --git a/nomad/structs/diff/structs.go b/nomad/structs/diff/structs.go deleted file mode 100644 index e92465dfb..000000000 --- a/nomad/structs/diff/structs.go +++ /dev/null @@ -1,25 +0,0 @@ -package diff - -import "github.com/hashicorp/nomad/nomad/structs" - -// JobPlanResponse is used to respond to a job plan request. Must be in this -// package to avoid a cyclic dependency. -type JobPlanResponse struct { - // Plan holds the decisions the scheduler made. - Plan *structs.Plan - - // The Cas value can be used when running `nomad run` to ensure that the Job - // wasn’t modified since the last plan. If the job is being created, the - // value is zero. - Cas uint64 - - // CreatedEvals is the set of evaluations created by the scheduler. The - // reasons for this can be rolling-updates or blocked evals. - CreatedEvals []*structs.Evaluation - - // Diff contains the diff of the job and annotations on whether the change - // causes an in-place update or create/destroy - Diff *JobDiff - - structs.QueryMeta -} diff --git a/nomad/structs/job_diff.go b/nomad/structs/job_diff.go deleted file mode 100644 index a6bf98bba..000000000 --- a/nomad/structs/job_diff.go +++ /dev/null @@ -1,1148 +0,0 @@ -package structs - -import ( - "fmt" - "reflect" - - "github.com/hashicorp/nomad/helper/flatmap" - "github.com/mitchellh/hashstructure" -) - -// The below are the set of primitive fields that can be diff'd automatically -// using FieldDiff. -var ( - jobPrimitiveFields = []string{ - "Region", - "ID", - "ParentID", - "Name", - "Type", - "Priority", - "AllAtOnce", - } - - constraintFields = []string{ - "LTarget", - "RTarget", - "Operand", - } - - updateStrategyFields = []string{ - "Stagger", - "MaxParallel", - } - - periodicConfigFields = []string{ - "Enabled", - "Spec", - "SpecType", - "ProhibitOverlap", - } - - taskGroupPrimitiveFields = []string{ - "Name", - "Count", - } - - restartPolicyFields = []string{ - "Attempts", - "Interval", - "Delay", - "Mode", - } - - taskPrimitiveFields = []string{ - "Name", - "Driver", - "User", - "KillTimeout", - } - - logConfigFields = []string{ - "MaxFiles", - "MaxFileSizeMB", - } - - servicePrimitiveFields = []string{ - "Name", - "PortLabel", - } - - serviceCheckPrimitiveFields = []string{ - "Name", - "Type", - "Command", - "Path", - "Protocol", - "Interval", - "Timeout", - } - - taskArtifactPrimitiveFields = []string{ - "GetterSource", - "RelativeDest", - } - - resourcesPrimitiveFields = []string{ - "CPU", - "MemoryMB", - "DiskMB", - "IOPS", - } - - networkResourcePrimitiveFields = []string{ - "Device", - "CIDR", - "IP", - "MBits", - } - - portFields = []string{ - "Label", - "Value", - } -) - -// DiffType is the high-level type of the diff. -type DiffType string - -const ( - DiffTypeNone DiffType = "Equal" - DiffTypeAdded = "Added" - DiffTypeDeleted = "Deleted" - DiffTypeEdited = "Edited" -) - -// DiffEntry contains information about a diff. -type DiffEntry struct { - Type DiffType - Annotations []string -} - -// SetDiffType sets the diff type. The inputs must be a pointer. -func (d *DiffEntry) SetDiffType(old, new interface{}) { - if reflect.DeepEqual(old, new) { - d.Type = DiffTypeNone - return - } - - oldV := reflect.ValueOf(old) - newV := reflect.ValueOf(new) - - if oldV.IsNil() { - d.Type = DiffTypeAdded - } else if newV.IsNil() { - d.Type = DiffTypeDeleted - } else { - d.Type = DiffTypeEdited - } -} - -// JobDiff contains the set of changes betwen two Jobs. -type JobDiff struct { - PrimitiveStructDiff - Constraints []*PrimitiveStructDiff - Datacenters *StringSetDiff - Update *PrimitiveStructDiff - Periodic *PrimitiveStructDiff - Meta *StringMapDiff - TaskGroups *TaskGroupsDiff -} - -// TaskGroupsDiff contains the set of Task Groups that were changed. -type TaskGroupsDiff struct { - DiffEntry - Added, Deleted []*TaskGroup - Edited []*TaskGroupDiff -} - -// TaskGroupsDiff contains the set of changes between two Task Groups. -type TaskGroupDiff struct { - PrimitiveStructDiff - Constraints []*PrimitiveStructDiff - RestartPolicy *PrimitiveStructDiff - Meta *StringMapDiff - Tasks *TasksDiff -} - -// TasksDiff contains the set of Tasks that were changed. -type TasksDiff struct { - DiffEntry - Added, Deleted []*Task - Edited []*TaskDiff -} - -// TaskDiff contains the changes between two Tasks. -type TaskDiff struct { - PrimitiveStructDiff - Constraints []*PrimitiveStructDiff - LogConfig *PrimitiveStructDiff - Env *StringMapDiff - Meta *StringMapDiff - Services *ServicesDiff - Artifacts *TaskArtifactsDiff - Resources *ResourcesDiff - Config *StringMapDiff -} - -// ServicesDiff contains the set of Services that were changed. -type ServicesDiff struct { - DiffEntry - Added, Deleted []*Service - Edited []*ServiceDiff -} - -// ServiceDiff contains the changes between two Services. -type ServiceDiff struct { - PrimitiveStructDiff - Tags *StringSetDiff - Checks *ServiceChecksDiff -} - -// ServiceChecksDiff contains the set of Service Checks that were changed. -type ServiceChecksDiff struct { - DiffEntry - Added, Deleted []*ServiceCheck - Edited []*ServiceCheckDiff -} - -// ServiceCheckDiff contains the changes between two Service Checks. -type ServiceCheckDiff struct { - PrimitiveStructDiff - Args *StringSetDiff -} - -// TaskArtifactsDiff contains the set of Task Artifacts that were changed. -type TaskArtifactsDiff struct { - DiffEntry - Added, Deleted []*TaskArtifact - Edited []*TaskArtifactDiff -} - -// TaskArtifactDiff contains the diff between two Task Artifacts. -type TaskArtifactDiff struct { - PrimitiveStructDiff - GetterOptions *StringMapDiff -} - -// ResourcesDiff contains the diff between two Resources. -type ResourcesDiff struct { - PrimitiveStructDiff - Networks *NetworkResourcesDiff -} - -// NetworkResourcesDiff contains the set of Network Resources that were changed. -type NetworkResourcesDiff struct { - DiffEntry - Added, Deleted []*NetworkResourceDiff -} - -// NetworkResourceDiff contains the diff between two Network Resources. -type NetworkResourceDiff struct { - PrimitiveStructDiff - ReservedPorts *PortsDiff - DynamicPorts *PortsDiff -} - -// PortsDiff contains the difference between two sets of Ports. -type PortsDiff struct { - DiffEntry - Added, Deleted []Port - Edited []*PrimitiveStructDiff -} - -// PrimitiveStructDiff contains the diff of two structs that only contain -// primitive fields. -type PrimitiveStructDiff struct { - DiffEntry - PrimitiveFields map[string]*FieldDiff -} - -// DiffFields performs the diff of the passed fields against the old and new -// object. -func (p *PrimitiveStructDiff) DiffFields(old, new interface{}, fields []string) { - for _, field := range fields { - oldV := getField(old, field) - newV := getField(new, field) - pDiff := NewFieldDiff(field, oldV, newV) - if pDiff != nil { - if p.PrimitiveFields == nil { - p.PrimitiveFields = make(map[string]*FieldDiff) - } - - p.PrimitiveFields[field] = pDiff - } - } -} - -// FieldDiff contains the diff between an old and new version of a field. -type FieldDiff struct { - DiffEntry - Name string - OldValue interface{} - NewValue interface{} -} - -// StringSetDiff captures the changes that occured between two sets of strings -type StringSetDiff struct { - DiffEntry - Added, Deleted []string -} - -// StringMapDiff captures the changes that occured between two string maps -type StringMapDiff struct { - DiffEntry - Added, Deleted map[string]string - Edited map[string]StringValueDelta -} - -// StringValueDelta holds the old and new value of a string. -type StringValueDelta struct { - DiffEntry - Old, New string -} - -// NewJobDiff returns the diff between two jobs. If there is no difference, nil -// is returned. -func NewJobDiff(old, new *Job) *JobDiff { - diff := &JobDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, jobPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &Job{} - } - if new == nil { - new = &Job{} - } - - // Get the diff of the datacenters - diff.Datacenters = NewStringSetDiff(old.Datacenters, new.Datacenters) - - // Get the diff of the constraints. - diff.Constraints = setDiffPrimitiveStructs( - interfaceSlice(old.Constraints), - interfaceSlice(new.Constraints), - constraintFields) - - // Get the update strategy diff - diff.Update = NewPrimitiveStructDiff(old.Update, new.Update, updateStrategyFields) - - // Get the update strategy diff - diff.Periodic = NewPrimitiveStructDiff(old.Periodic, new.Periodic, periodicConfigFields) - - // Get the meta diff - diff.Meta = NewStringMapDiff(old.Meta, new.Meta) - - // Get the task group diff - diff.TaskGroups = setDiffTaskGroups(old.TaskGroups, new.TaskGroups) - - // If there are no changes return nil - if len(diff.PrimitiveFields)+len(diff.Constraints) == 0 && - diff.Datacenters == nil && - diff.Update == nil && - diff.Periodic == nil && - diff.Meta == nil && - diff.TaskGroups == nil { - return nil - } - - return diff -} - -// NewTaskGroupDiff returns the diff between two task groups. If there is no -// difference, nil is returned. -func NewTaskGroupDiff(old, new *TaskGroup) *TaskGroupDiff { - diff := &TaskGroupDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, taskGroupPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &TaskGroup{} - } - if new == nil { - new = &TaskGroup{} - } - - // Get the diff of the constraints. - diff.Constraints = setDiffPrimitiveStructs( - interfaceSlice(old.Constraints), - interfaceSlice(new.Constraints), - constraintFields) - - // Get the restart policy diff - diff.RestartPolicy = NewPrimitiveStructDiff(old.RestartPolicy, new.RestartPolicy, restartPolicyFields) - - // Get the meta diff - diff.Meta = NewStringMapDiff(old.Meta, new.Meta) - - // Get the task diff - diff.Tasks = setDiffTasks(old.Tasks, new.Tasks) - - // If there are no changes return nil - if len(diff.PrimitiveFields)+len(diff.Constraints) == 0 && - diff.Tasks == nil && - diff.RestartPolicy == nil && - diff.Meta == nil { - return nil - } - - return diff -} - -// NewTaskDiff returns the diff between two tasks. If there is no difference, -// nil is returned. -func NewTaskDiff(old, new *Task) *TaskDiff { - diff := &TaskDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, taskPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &Task{} - } - if new == nil { - new = &Task{} - } - - // Get the diff of the constraints. - diff.Constraints = setDiffPrimitiveStructs( - interfaceSlice(old.Constraints), - interfaceSlice(new.Constraints), - constraintFields) - - // Get the meta and env diff - diff.Meta = NewStringMapDiff(old.Meta, new.Meta) - diff.Env = NewStringMapDiff(old.Env, new.Env) - - // Get the log config diff - diff.LogConfig = NewPrimitiveStructDiff(old.LogConfig, new.LogConfig, logConfigFields) - - // Get the services diff - diff.Services = setDiffServices(old.Services, new.Services) - - // Get the artifacts diff - diff.Artifacts = setDiffTaskArtifacts(old.Artifacts, new.Artifacts) - - // Get the resource diff - diff.Resources = NewResourcesDiff(old.Resources, new.Resources) - - // Get the task config diff - diff.Config = NewStringMapDiff(flatmap.Flatten(old.Config), flatmap.Flatten(new.Config)) - - // If there are no changes return nil - if len(diff.PrimitiveFields)+len(diff.Constraints) == 0 && - diff.Config == nil && - diff.Artifacts == nil && - diff.LogConfig == nil && - diff.Services == nil && - diff.Env == nil && - diff.Meta == nil { - return nil - } - - return diff -} - -// NewServiceDiff returns the diff between two services. If there is no -// difference, nil is returned. -func NewServiceDiff(old, new *Service) *ServiceDiff { - diff := &ServiceDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, servicePrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &Service{} - } - if new == nil { - new = &Service{} - } - - // Get the tags diff - diff.Tags = NewStringSetDiff(old.Tags, new.Tags) - - // Get the checks diff - diff.Checks = setDiffServiceChecks(old.Checks, new.Checks) - - // If there are no changes return nil - if len(diff.PrimitiveFields) == 0 && - diff.Checks == nil && - diff.Tags == nil { - return nil - } - - return diff -} - -// NewServiceCheckDiff returns the diff between two service checks. If there is -// no difference, nil is returned. -func NewServiceCheckDiff(old, new *ServiceCheck) *ServiceCheckDiff { - diff := &ServiceCheckDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, serviceCheckPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &ServiceCheck{} - } - if new == nil { - new = &ServiceCheck{} - } - - // Get the args diff - diff.Args = NewStringSetDiff(old.Args, new.Args) - - // If there are no changes return nil - if len(diff.PrimitiveFields) == 0 && - diff.Args == nil { - return nil - } - - return diff -} - -// NewTaskArtifactDiff returns the diff between two task artifacts. If there is -// no difference, nil is returned. -func NewTaskArtifactDiff(old, new *TaskArtifact) *TaskArtifactDiff { - diff := &TaskArtifactDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, taskArtifactPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &TaskArtifact{} - } - if new == nil { - new = &TaskArtifact{} - } - - // Get the args diff - diff.GetterOptions = NewStringMapDiff(old.GetterOptions, new.GetterOptions) - - // If there are no changes return nil - if len(diff.PrimitiveFields) == 0 && - diff.GetterOptions == nil { - return nil - } - - return diff -} - -// NewResourcesDiff returns the diff between two resources. If there is no -// difference, nil is returned. -func NewResourcesDiff(old, new *Resources) *ResourcesDiff { - diff := &ResourcesDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, resourcesPrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &Resources{} - } - if new == nil { - new = &Resources{} - } - - // Get the network resource diff - diff.Networks = setDiffNetworkResources(old.Networks, new.Networks) - - // If there are no changes return nil - if len(diff.PrimitiveFields) == 0 && - diff.Networks == nil { - return nil - } - - return diff -} - -// NewNetworkResourceDiff returns the diff between two network resources. If -// there is no difference, nil is returned. -func NewNetworkResourceDiff(old, new *NetworkResource) *NetworkResourceDiff { - diff := &NetworkResourceDiff{} - diff.SetDiffType(old, new) - if diff.Type == DiffTypeNone { - return nil - } - - // Get the diffs of the primitive fields - diff.DiffFields(old, new, networkResourcePrimitiveFields) - - // Protect accessing nil fields, this occurs after diffing the primitives so - // that we can properly detect Added/Deleted fields. - if old == nil { - old = &NetworkResource{} - } - if new == nil { - new = &NetworkResource{} - } - - // Get the port diffs - diff.ReservedPorts = setDiffPorts(old.ReservedPorts, new.ReservedPorts) - diff.DynamicPorts = setDiffPorts(old.DynamicPorts, new.DynamicPorts) - - // If there are no changes return nil - if len(diff.PrimitiveFields) == 0 && - diff.DynamicPorts == nil && - diff.ReservedPorts == nil { - return nil - } - - return diff -} - -// NewPrimitiveStructDiff returns the diff between two structs containing only -// primitive fields. The list of fields to be diffed is passed via the fields -// parameter. If there is no difference, nil is returned. -func NewPrimitiveStructDiff(old, new interface{}, fields []string) *PrimitiveStructDiff { - if reflect.DeepEqual(old, new) { - return nil - } - - // Diff the individual fields - diff := &PrimitiveStructDiff{} - diff.DiffFields(old, new, fields) - if len(diff.PrimitiveFields) == 0 { - return nil - } - - var added, deleted bool - for _, f := range diff.PrimitiveFields { - switch f.Type { - case DiffTypeEdited: - diff.Type = DiffTypeEdited - return diff - case DiffTypeAdded: - added = true - case DiffTypeDeleted: - deleted = true - } - } - - if added && deleted { - diff.Type = DiffTypeEdited - } else if added { - diff.Type = DiffTypeAdded - } else { - diff.Type = DiffTypeDeleted - } - - return diff -} - -// NewFieldDiff returns the diff between two fields. If there is no difference, -// nil is returned. -func NewFieldDiff(name string, old, new interface{}) *FieldDiff { - diff := &FieldDiff{Name: name} - if reflect.DeepEqual(old, new) { - return nil - } else if old == nil { - diff.Type = DiffTypeAdded - diff.NewValue = new - } else if new == nil { - diff.Type = DiffTypeDeleted - diff.OldValue = old - } else { - diff.Type = DiffTypeEdited - diff.OldValue = old - diff.NewValue = new - } - - return diff -} - -// NewStringSetDiff returns the diff between two sets of strings. If there is no -// difference, nil is returned. -func NewStringSetDiff(old, new []string) *StringSetDiff { - if reflect.DeepEqual(old, new) { - return nil - } - - diff := &StringSetDiff{} - makeMap := func(inputs []string) map[string]interface{} { - m := make(map[string]interface{}) - for _, in := range inputs { - m[in] = struct{}{} - } - return m - } - - added, deleted, _, _ := keyedSetDifference(makeMap(old), makeMap(new)) - for k := range added { - diff.Added = append(diff.Added, k) - } - for k := range deleted { - diff.Deleted = append(diff.Deleted, k) - } - - la, ld := len(added), len(deleted) - if la+ld == 0 { - return nil - } else if ld == 0 { - diff.Type = DiffTypeAdded - } else if la == 0 { - diff.Type = DiffTypeDeleted - } else { - diff.Type = DiffTypeEdited - } - - return diff -} - -// NewStringMapDiff returns the diff between two maps of strings. If there is no -// difference, nil is returned. -func NewStringMapDiff(old, new map[string]string) *StringMapDiff { - if reflect.DeepEqual(old, new) { - return nil - } - - diff := &StringMapDiff{} - diff.Added = make(map[string]string) - diff.Deleted = make(map[string]string) - diff.Edited = make(map[string]StringValueDelta) - - for k, v := range old { - if _, ok := new[k]; !ok { - diff.Deleted[k] = v - } - } - for k, newV := range new { - oldV, ok := old[k] - if !ok { - diff.Added[k] = newV - continue - } - - // Key is in both, check if they have been edited. - if newV != oldV { - d := StringValueDelta{Old: oldV, New: newV} - d.Type = DiffTypeEdited - diff.Edited[k] = d - } - } - - la, ld, le := len(diff.Added), len(diff.Deleted), len(diff.Edited) - if la+ld+le == 0 { - return nil - } - - if le != 0 || la > 0 && ld > 0 { - diff.Type = DiffTypeEdited - } else if ld == 0 { - diff.Type = DiffTypeAdded - } else if la == 0 { - diff.Type = DiffTypeDeleted - } - return diff -} - -// Set helpers - -// setDiffTaskGroups does a set difference of task groups using the task group -// name as a key. -func setDiffTaskGroups(old, new []*TaskGroup) *TaskGroupsDiff { - diff := &TaskGroupsDiff{} - - oldMap := make(map[string]*TaskGroup) - newMap := make(map[string]*TaskGroup) - for _, tg := range old { - oldMap[tg.Name] = tg - } - for _, tg := range new { - newMap[tg.Name] = tg - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - tgdiff := NewTaskGroupDiff(oldV, newV) - diff.Edited = append(diff.Edited, tgdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffTasks does a set difference of tasks using the task name as a key. -func setDiffTasks(old, new []*Task) *TasksDiff { - diff := &TasksDiff{} - - oldMap := make(map[string]*Task) - newMap := make(map[string]*Task) - for _, task := range old { - oldMap[task.Name] = task - } - for _, task := range new { - newMap[task.Name] = task - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - tdiff := NewTaskDiff(oldV, newV) - diff.Edited = append(diff.Edited, tdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffServices does a set difference of Services using the service name as a -// key. -func setDiffServices(old, new []*Service) *ServicesDiff { - diff := &ServicesDiff{} - - oldMap := make(map[string]*Service) - newMap := make(map[string]*Service) - for _, s := range old { - oldMap[s.Name] = s - } - for _, s := range new { - newMap[s.Name] = s - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - sdiff := NewServiceDiff(oldV, newV) - diff.Edited = append(diff.Edited, sdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffServiceChecks does a set difference of service checks using the check -// name as a key. -func setDiffServiceChecks(old, new []*ServiceCheck) *ServiceChecksDiff { - diff := &ServiceChecksDiff{} - - oldMap := make(map[string]*ServiceCheck) - newMap := make(map[string]*ServiceCheck) - for _, s := range old { - oldMap[s.Name] = s - } - for _, s := range new { - newMap[s.Name] = s - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - sdiff := NewServiceCheckDiff(oldV, newV) - diff.Edited = append(diff.Edited, sdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffTaskArtifacts does a set difference of task artifacts using the geter -// source as a key. -func setDiffTaskArtifacts(old, new []*TaskArtifact) *TaskArtifactsDiff { - diff := &TaskArtifactsDiff{} - - oldMap := make(map[string]*TaskArtifact) - newMap := make(map[string]*TaskArtifact) - for _, ta := range old { - oldMap[ta.GetterSource] = ta - } - for _, ta := range new { - newMap[ta.GetterSource] = ta - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - tdiff := NewTaskArtifactDiff(oldV, newV) - diff.Edited = append(diff.Edited, tdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffNetworkResources does a set difference of network resources. -func setDiffNetworkResources(old, new []*NetworkResource) *NetworkResourcesDiff { - diff := &NetworkResourcesDiff{} - - added, del := setDifference(interfaceSlice(old), interfaceSlice(new)) - for _, a := range added { - nDiff := NewNetworkResourceDiff(nil, a.(*NetworkResource)) - diff.Added = append(diff.Added, nDiff) - } - for _, d := range del { - nDiff := NewNetworkResourceDiff(d.(*NetworkResource), nil) - diff.Added = append(diff.Deleted, nDiff) - } - - return diff -} - -// setDiffPorts does a set difference of ports using the label as a key. -func setDiffPorts(old, new []Port) *PortsDiff { - diff := &PortsDiff{} - - oldMap := make(map[string]Port) - newMap := make(map[string]Port) - for _, p := range old { - oldMap[p.Label] = p - } - for _, p := range new { - newMap[p.Label] = p - } - - for k, v := range oldMap { - if _, ok := newMap[k]; !ok { - diff.Deleted = append(diff.Deleted, v) - } - } - for k, newV := range newMap { - oldV, ok := oldMap[k] - if !ok { - diff.Added = append(diff.Added, newV) - continue - } - - // Key is in both, check if they have been edited. - if !reflect.DeepEqual(oldV, newV) { - pdiff := NewPrimitiveStructDiff(oldV, newV, portFields) - diff.Edited = append(diff.Edited, pdiff) - } - } - - if len(diff.Added)+len(diff.Deleted)+len(diff.Edited) == 0 { - return nil - } - return diff -} - -// setDiffPrimitiveStructs does a set difference on primitive structs. The -// caller must pass the primitive structs fields. -func setDiffPrimitiveStructs(old, new []interface{}, fields []string) []*PrimitiveStructDiff { - var diffs []*PrimitiveStructDiff - - added, del := setDifference(old, new) - for _, a := range added { - pDiff := NewPrimitiveStructDiff(nil, a, fields) - diffs = append(diffs, pDiff) - } - for _, d := range del { - pDiff := NewPrimitiveStructDiff(d, nil, fields) - diffs = append(diffs, pDiff) - } - - return diffs -} - -// Reflective helpers. - -// setDifference does a set difference on two sets of interfaces and returns the -// values that were added or deleted when comparing the new to old. -func setDifference(old, new []interface{}) (added, deleted []interface{}) { - makeSet := func(objects []interface{}) map[string]interface{} { - objMap := make(map[string]interface{}, len(objects)) - for _, obj := range objects { - hash, err := hashstructure.Hash(obj, nil) - if err != nil { - panic(err) - } - objMap[fmt.Sprintf("%d", hash)] = obj - } - - return objMap - } - - addedMap, deletedMap, _, _ := keyedSetDifference(makeSet(old), makeSet(new)) - flatten := func(in map[string]interface{}) []interface{} { - out := make([]interface{}, 0, len(in)) - for _, v := range in { - out = append(out, v) - } - return out - } - - return flatten(addedMap), flatten(deletedMap) -} - -// keyedSetDifference does a set difference on keyed object and returns the -// objects that have been added, deleted, edited and unmodified when comparing -// the new to old set. -func keyedSetDifference(old, new map[string]interface{}) ( - added, deleted map[string]interface{}, edited, unmodified []string) { - - added = make(map[string]interface{}) - deleted = make(map[string]interface{}) - - for k, v := range old { - if _, ok := new[k]; !ok { - deleted[k] = v - } - } - for k, newV := range new { - oldV, ok := old[k] - if !ok { - added[k] = newV - continue - } - - // Key is in both, check if they have been edited. - if reflect.DeepEqual(oldV, newV) { - unmodified = append(unmodified, k) - } else { - edited = append(edited, k) - } - } - - return added, deleted, edited, unmodified -} - -// interfaceSlice is a helper method that takes a slice of typed elements and -// returns a slice of interface. This method will panic if given a non-slice -// input. -func interfaceSlice(slice interface{}) []interface{} { - s := reflect.ValueOf(slice) - if s.Kind() != reflect.Slice { - panic("InterfaceSlice() given a non-slice type") - } - - ret := make([]interface{}, s.Len()) - - for i := 0; i < s.Len(); i++ { - ret[i] = s.Index(i).Interface() - } - - return ret -} - -// getField is a helper that returns the passed fields value of the given -// object. This method will panic if the field does not exist in the passed -// object. -func getField(obj interface{}, field string) interface{} { - if obj == nil { - return nil - } - - r := reflect.ValueOf(obj) - r = reflect.Indirect(r) - if !r.IsValid() { - return nil - } - - f := r.FieldByName(field) - return f.Interface() -} diff --git a/nomad/structs/job_diff_test.go b/nomad/structs/job_diff_test.go deleted file mode 100644 index 1db2ebb8e..000000000 --- a/nomad/structs/job_diff_test.go +++ /dev/null @@ -1,673 +0,0 @@ -package structs - -import ( - "reflect" - "sort" - "testing" -) - -func TestNewJobDiff_Same(t *testing.T) { - job1 := TestJob() - job2 := TestJob() - job2.ID = job1.ID - - diff := NewJobDiff(job1, job2) - if diff != nil { - t.Fatalf("expected nil job diff; got %#v", diff) - } -} - -func TestNewJobDiff_NilCases(t *testing.T) { - j := TestJob() - - // Old job nil - diff := NewJobDiff(nil, j) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - if diff.Type != DiffTypeAdded { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeAdded) - } - - // New job nil - diff = NewJobDiff(j, nil) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - if diff.Type != DiffTypeDeleted { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeDeleted) - } -} - -func TestNewJobDiff_Constraints(t *testing.T) { - c1 := &Constraint{LTarget: "foo"} - c2 := &Constraint{LTarget: "bar"} - c3 := &Constraint{LTarget: "baz"} - - // Test the added case. - j1 := &Job{Constraints: []*Constraint{c1, c2}} - j2 := &Job{Constraints: []*Constraint{c1, c2, c3}} - - diff := NewJobDiff(j1, j2) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - - if diff.Type != DiffTypeEdited { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeEdited) - } - - if len(diff.Constraints) != 1 { - t.Fatalf("expected one constraint diff; got %v", diff.Constraints) - } - - cdiff := diff.Constraints[0] - if cdiff.Type != DiffTypeAdded { - t.Fatalf("expected constraint to be added: %#v", cdiff) - } - if len(cdiff.PrimitiveFields) != 3 { - t.Fatalf("bad: %#v", cdiff) - } - - // Test the deleted case. - j1 = &Job{Constraints: []*Constraint{c1, c2}} - j2 = &Job{Constraints: []*Constraint{c1}} - - diff = NewJobDiff(j1, j2) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - - if diff.Type != DiffTypeEdited { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeEdited) - } - - if len(diff.Constraints) != 1 { - t.Fatalf("expected one constraint diff; got %v", diff.Constraints) - } - - cdiff = diff.Constraints[0] - if cdiff.Type != DiffTypeDeleted { - t.Fatalf("expected constraint to be deleted: %#v", cdiff) - } - if len(cdiff.PrimitiveFields) != 3 { - t.Fatalf("bad: %#v", cdiff) - } -} - -func TestNewJobDiff_Datacenters(t *testing.T) { - j1 := &Job{Datacenters: []string{"a", "b"}} - j2 := &Job{Datacenters: []string{"b", "c"}} - - diff := NewJobDiff(j1, j2) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - - if diff.Type != DiffTypeEdited { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeEdited) - } - - dd := diff.Datacenters - if dd == nil { - t.Fatalf("expected datacenter diff") - } - - if !reflect.DeepEqual(dd.Added, []string{"c"}) || - !reflect.DeepEqual(dd.Deleted, []string{"a"}) { - t.Fatalf("bad: %#v", dd) - } - -} - -func TestNewJobDiff_TaskGroups(t *testing.T) { - tg1 := &TaskGroup{Name: "foo"} - tg2 := &TaskGroup{Name: "bar"} - tg2_2 := &TaskGroup{Name: "bar", Count: 2} - tg3 := &TaskGroup{Name: "baz"} - - j1 := &Job{TaskGroups: []*TaskGroup{tg1, tg2}} - j2 := &Job{TaskGroups: []*TaskGroup{tg2_2, tg3}} - - diff := NewJobDiff(j1, j2) - if diff == nil { - t.Fatalf("expected non-nil job diff") - } - - if diff.Type != DiffTypeEdited { - t.Fatalf("got diff type %v; want %v", diff.Type, DiffTypeEdited) - } - - tgd := diff.TaskGroups - if tgd == nil { - t.Fatalf("expected task group diff") - } - - if !reflect.DeepEqual(tgd.Added, []*TaskGroup{tg3}) || - !reflect.DeepEqual(tgd.Deleted, []*TaskGroup{tg1}) { - t.Fatalf("bad: %#v", tgd) - } - - if len(tgd.Edited) != 1 { - t.Fatalf("expect one edited task group: %#v", tgd) - } - if e := tgd.Edited[0]; tgd.Type != DiffTypeEdited && len(e.PrimitiveFields) != 1 { - t.Fatalf("bad: %#v", e) - } -} - -func TestNewTaskDiff_Config(t *testing.T) { - c1 := map[string]interface{}{ - "command": "/bin/date", - "args": []string{"1", "2"}, - } - - c2 := map[string]interface{}{ - "args": []string{"1", "2"}, - } - - c3 := map[string]interface{}{ - "command": "/bin/date", - "args": []string{"1", "2"}, - "nested": &Port{ - Label: "http", - Value: 80, - }, - } - - c4 := map[string]interface{}{ - "command": "/bin/bash", - "args": []string{"1", "2"}, - } - - // No old case - t1 := &Task{Config: c1} - diff := NewTaskDiff(nil, t1) - if diff == nil { - t.Fatalf("expected non-nil diff") - } - if diff.Config == nil { - t.Fatalf("expected Config diff: %#v", diff) - } - - cdiff := diff.Config - if cdiff.Type != DiffTypeAdded { - t.Fatalf("expected Config diff type %v; got %#v", DiffTypeAdded, cdiff.Type) - } - - // No new case - diff = NewTaskDiff(t1, nil) - if diff == nil { - t.Fatalf("expected non-nil diff") - } - if diff.Config == nil { - t.Fatalf("expected Config diff: %#v", diff) - } - - cdiff = diff.Config - if cdiff.Type != DiffTypeDeleted { - t.Fatalf("expected Config diff type %v; got %#v", DiffTypeDeleted, cdiff.Type) - } - - // Same case - diff = NewTaskDiff(t1, t1) - if diff != nil { - t.Fatalf("expected nil diff") - } - - // Deleted case - t2 := &Task{Config: c2} - diff = NewTaskDiff(t1, t2) - if diff == nil { - t.Fatalf("expected non-nil diff") - } - if diff.Config == nil { - t.Fatalf("expected Config diff: %#v", diff) - } - - cdiff = diff.Config - if cdiff.Type != DiffTypeDeleted { - t.Fatalf("expected Config diff type %v; got %#v", DiffTypeDeleted, cdiff.Type) - } - - if len(cdiff.Added)+len(cdiff.Edited) != 0 && len(cdiff.Deleted) != 1 { - t.Fatalf("unexpected config diffs: %#v", cdiff) - } - - if v, ok := cdiff.Deleted["command"]; !ok || v != "/bin/date" { - t.Fatalf("bad: %#v", cdiff.Deleted) - } - - // Added case - t3 := &Task{Config: c3} - diff = NewTaskDiff(t1, t3) - if diff == nil { - t.Fatalf("expected non-nil diff") - } - if diff.Config == nil { - t.Fatalf("expected Config diff: %#v", diff) - } - - cdiff = diff.Config - if cdiff.Type != DiffTypeAdded { - t.Fatalf("expected Config diff type %v; got %#v", DiffTypeAdded, cdiff.Type) - } - - if len(cdiff.Deleted)+len(cdiff.Edited) != 0 && len(cdiff.Added) != 2 { - t.Fatalf("unexpected config diffs: %#v", cdiff) - } - - if v, ok := cdiff.Added["nested.Value"]; !ok || v != "80" { - t.Fatalf("bad: %#v", cdiff.Added) - } - if v, ok := cdiff.Added["nested.Label"]; !ok || v != "http" { - t.Fatalf("bad: %#v", cdiff.Added) - } - - // Edited case - t4 := &Task{Config: c4} - diff = NewTaskDiff(t1, t4) - if diff == nil { - t.Fatalf("expected non-nil diff") - } - if diff.Config == nil { - t.Fatalf("expected Config diff: %#v", diff) - } - - cdiff = diff.Config - if cdiff.Type != DiffTypeEdited { - t.Fatalf("expected Config diff type %v; got %#v", DiffTypeEdited, cdiff.Type) - } - - if len(cdiff.Deleted)+len(cdiff.Added) != 0 && len(cdiff.Edited) != 1 { - t.Fatalf("unexpected config diffs: %#v", cdiff) - } - - exp := StringValueDelta{Old: "/bin/date", New: "/bin/bash"} - exp.Type = DiffTypeEdited - v, ok := cdiff.Edited["command"] - if !ok || !reflect.DeepEqual(v, exp) { - t.Fatalf("bad: %#v %#v %#v", cdiff.Edited, v, exp) - } -} - -func TestNewPrimitiveStructDiff(t *testing.T) { - p1 := Port{Label: "1"} - p2 := Port{Label: "2"} - p3 := Port{} - - pdiff := NewPrimitiveStructDiff(nil, nil, portFields) - if pdiff != nil { - t.Fatalf("expected no diff: %#v", pdiff) - } - - pdiff = NewPrimitiveStructDiff(p1, p1, portFields) - if pdiff != nil { - t.Fatalf("expected no diff: %#v", pdiff) - } - - pdiff = NewPrimitiveStructDiff(nil, p1, portFields) - if pdiff == nil { - t.Fatalf("expected diff") - } - - if pdiff.Type != DiffTypeAdded { - t.Fatalf("unexpected type: got %v; want %v", pdiff.Type, DiffTypeAdded) - } - - pdiff = NewPrimitiveStructDiff(p1, nil, portFields) - if pdiff == nil { - t.Fatalf("expected diff") - } - - if pdiff.Type != DiffTypeDeleted { - t.Fatalf("unexpected type: got %v; want %v", pdiff.Type, DiffTypeDeleted) - } - - pdiff = NewPrimitiveStructDiff(p1, p2, portFields) - if pdiff == nil { - t.Fatalf("expected diff") - } - - if pdiff.Type != DiffTypeEdited { - t.Fatalf("unexpected type: got %v; want %v", pdiff.Type, DiffTypeEdited) - } - - if len(pdiff.PrimitiveFields) != 1 { - t.Fatalf("unexpected number of field diffs: %#v", pdiff.PrimitiveFields) - } - - f, ok := pdiff.PrimitiveFields["Label"] - if !ok { - t.Fatalf("expected diff on field %q", "label") - } - - if f.Type != DiffTypeEdited { - t.Fatalf("unexpected type: got %v; want %v", f.Type, DiffTypeEdited) - } - if !reflect.DeepEqual(f.OldValue, "1") || !reflect.DeepEqual(f.NewValue, "2") { - t.Fatalf("bad: %#v", f) - } - - pdiff = NewPrimitiveStructDiff(p1, p3, portFields) - if pdiff == nil { - t.Fatalf("expected diff") - } - - if pdiff.Type != DiffTypeEdited { - t.Fatalf("unexpected type: got %v; want %v", pdiff.Type, DiffTypeEdited) - } - - if len(pdiff.PrimitiveFields) != 1 { - t.Fatalf("unexpected number of field diffs: %#v", pdiff.PrimitiveFields) - } - - f = pdiff.PrimitiveFields["Label"] - if !ok { - t.Fatalf("expected diff on field %q", "Label") - } - if f.Type != DiffTypeEdited { - t.Fatalf("unexpected type: got %v; want %v", f.Type, DiffTypeEdited) - } - if !reflect.DeepEqual(f.OldValue, "1") || !reflect.DeepEqual(f.NewValue, "") { - t.Fatalf("bad: %#v", f) - } -} - -func TestSetDiffPrimitiveStructs(t *testing.T) { - p1 := Port{Label: "1"} - p2 := Port{Label: "2"} - p3 := Port{Label: "3"} - p4 := Port{Label: "4"} - p5 := Port{Label: "5"} - p6 := Port{Label: "6"} - - old := []Port{p1, p2, p3, p4} - new := []Port{p3, p4, p5, p6} - - diffs := setDiffPrimitiveStructs(interfaceSlice(old), interfaceSlice(new), portFields) - if len(diffs) != 4 { - t.Fatalf("expected four diffs: %#v", diffs) - } - - var added, deleted int - for _, diff := range diffs { - switch diff.Type { - case DiffTypeAdded: - added++ - case DiffTypeDeleted: - deleted++ - default: - t.Fatalf("unexpected diff type: %#v", diff.Type) - } - } - - if added != 2 && deleted != 2 { - t.Fatalf("incorrect counts") - } -} - -func TestNewFieldDiff(t *testing.T) { - cases := []struct { - NilExpected bool - Old, New interface{} - Expected DiffType - }{ - { - NilExpected: true, - Old: 1, - New: 1, - }, - { - NilExpected: true, - Old: true, - New: true, - }, - { - NilExpected: true, - Old: "foo", - New: "foo", - }, - { - NilExpected: true, - Old: 2.23, - New: 2.23, - }, - { - Old: 1, - New: 4, - Expected: DiffTypeEdited, - }, - { - Old: true, - New: false, - Expected: DiffTypeEdited, - }, - { - Old: "foo", - New: "bar", - Expected: DiffTypeEdited, - }, - { - Old: 2.23, - New: 12.511, - Expected: DiffTypeEdited, - }, - { - Old: nil, - New: 4, - Expected: DiffTypeAdded, - }, - { - Old: nil, - New: true, - Expected: DiffTypeAdded, - }, - { - Old: nil, - New: "bar", - Expected: DiffTypeAdded, - }, - { - Old: nil, - New: 12.511, - Expected: DiffTypeAdded, - }, - { - Old: 4, - New: nil, - Expected: DiffTypeDeleted, - }, - { - Old: true, - New: nil, - Expected: DiffTypeDeleted, - }, - { - Old: "bar", - New: nil, - Expected: DiffTypeDeleted, - }, - { - Old: 12.511, - New: nil, - Expected: DiffTypeDeleted, - }, - } - - for i, c := range cases { - diff := NewFieldDiff("foo", c.Old, c.New) - if diff == nil { - if !c.NilExpected { - t.Fatalf("case %d: diff was nil and unexpected", i+1) - } - continue - } - - if diff.Type != c.Expected { - t.Fatalf("case %d: wanted type %v; got %v", i+1, diff.Type, c.Expected) - } - } -} - -func TestStringSetDiff(t *testing.T) { - values := []string{"1", "2", "3", "4", "5", "6"} - - // Edited case - setDiff := NewStringSetDiff(values[:4], values[2:]) - if setDiff.Type != DiffTypeEdited { - t.Fatalf("got type %v; want %v", setDiff.Type, DiffTypeEdited) - } - - addedExp := []string{"5", "6"} - deletedExp := []string{"1", "2"} - sort.Strings(setDiff.Added) - sort.Strings(setDiff.Deleted) - - if !reflect.DeepEqual(addedExp, setDiff.Added) || - !reflect.DeepEqual(deletedExp, setDiff.Deleted) { - t.Fatalf("bad: %#v", setDiff) - } - - // Added case - setDiff = NewStringSetDiff(nil, values) - if setDiff.Type != DiffTypeAdded { - t.Fatalf("got type %v; want %v", setDiff.Type, DiffTypeAdded) - } - - // Deleted case - setDiff = NewStringSetDiff(values, nil) - if setDiff.Type != DiffTypeDeleted { - t.Fatalf("got type %v; want %v", setDiff.Type, DiffTypeDeleted) - } -} - -func TestStringMapDiff(t *testing.T) { - m1 := map[string]string{ - "a": "aval", - "b": "bval", - } - m2 := map[string]string{ - "b": "bval2", - "c": "cval", - } - - // Edited case - expected := &StringMapDiff{ - DiffEntry: DiffEntry{ - Type: DiffTypeEdited, - }, - Added: map[string]string{"c": "cval"}, - Deleted: map[string]string{"a": "aval"}, - Edited: map[string]StringValueDelta{ - "b": StringValueDelta{Old: "bval", - DiffEntry: DiffEntry{ - Type: DiffTypeEdited, - }, - New: "bval2", - }, - }, - } - - act := NewStringMapDiff(m1, m2) - if !reflect.DeepEqual(act, expected) { - t.Fatalf("got %#v; want %#v", act, expected) - } - - // Added case - diff := NewStringMapDiff(nil, m1) - if diff.Type != DiffTypeAdded { - t.Fatalf("got type %v; want %v", diff.Type, DiffTypeAdded) - } - - // Deleted case - diff = NewStringMapDiff(m1, nil) - if diff.Type != DiffTypeDeleted { - t.Fatalf("got type %v; want %v", diff.Type, DiffTypeDeleted) - } -} - -func TestSetDifference(t *testing.T) { - old := []interface{}{1, 2} - new := []interface{}{2, 3} - added, deleted := setDifference(old, new) - - if len(added) != 1 && len(deleted) != 1 { - t.Fatalf("bad: %#v %#v", added, deleted) - } - - a, ok := added[0].(int) - if !ok || a != 3 { - t.Fatalf("bad: %v %v", a, ok) - } - - d, ok := deleted[0].(int) - if !ok || d != 1 { - t.Fatalf("bad: %v %v", a, ok) - } -} - -func TestKeyedSetDifference(t *testing.T) { - oldMap := map[string]interface{}{ - "a": 1, - "b": 2, - "c": 3, - } - newMap := map[string]interface{}{ - "b": 3, - "c": 3, - "d": 4, - } - - added, deleted, edited, unmodified := keyedSetDifference(oldMap, newMap) - - if v, ok := added["d"]; !ok || v.(int) != 4 { - t.Fatalf("bad: %#v", added) - } - if v, ok := deleted["a"]; !ok || v.(int) != 1 { - t.Fatalf("bad: %#v", deleted) - } - if l := len(edited); l != 1 || edited[0] != "b" { - t.Fatalf("bad: %#v", edited) - } - if l := len(unmodified); l != 1 || unmodified[0] != "c" { - t.Fatalf("bad: %#v", edited) - } -} - -func TestInterfaceSlice(t *testing.T) { - j1 := TestJob() - j2 := TestJob() - jobs := []*Job{j1, j2} - - slice := interfaceSlice(jobs) - if len(slice) != 2 { - t.Fatalf("bad: %#v", slice) - } - - f := slice[0] - actJob1, ok := f.(*Job) - if !ok { - t.Fatalf("unexpected type: %v", actJob1) - } - - if !reflect.DeepEqual(actJob1, j1) { - t.Fatalf("got %#v, want %#v", actJob1, j1) - } -} - -func TestGetField(t *testing.T) { - j := TestJob() - exp := "foo" - j.Type = "foo" - - i := getField(j, "Type") - act, ok := i.(string) - if !ok { - t.Fatalf("expected to get string type back") - } - - if act != exp { - t.Fatalf("got %v; want %v", act, exp) - } -} diff --git a/nomad/structs/job_diff_visitor.go b/nomad/structs/job_diff_visitor.go deleted file mode 100644 index a1747fc6f..000000000 --- a/nomad/structs/job_diff_visitor.go +++ /dev/null @@ -1,52 +0,0 @@ -package structs - -// JobVisitor is the set of types a visitor must implement to traverse a JobDiff -// structure. -type JobVisitor interface { - VisitJob(*JobDiff) - VisitTaskGroups(*TaskGroupsDiff) - VisitTaskGroup(*TaskGroupDiff) - VisitTasks(*TasksDiff) - VisitTask(*TaskDiff) - VisitServices(*ServicesDiff) - VisitService(*ServiceDiff) - VisitServiceChecks(*ServiceChecksDiff) - VisitServiceCheck(*ServiceCheckDiff) - VisitTaskArtifactsDiff(*TaskArtifactsDiff) - VisitTaskArtifactDiff(*TaskArtifactDiff) - VisitResources(*ResourcesDiff) - VisitNetworkResources(*NetworkResourcesDiff) - VisitNetworkResource(*NetworkResourceDiff) - VisitPorts(*PortsDiff) - VisitPrimitiveStruct(*PrimitiveStructDiff) - VisitField(*FieldDiff) - VisitStringSet(*StringSetDiff) - VisitStringMap(*StringMapDiff) - VisitStringValueDelta(*StringValueDelta) -} - -// JobDiffComponent is the method a diff component must implement to be visited. -type JobDiffComponent interface { - Accept(JobVisitor) -} - -func (j *JobDiff) Accept(v JobVisitor) { v.VisitJob(j) } -func (t *TaskGroupsDiff) Accept(v JobVisitor) { v.VisitTaskGroups(t) } -func (t *TaskGroupDiff) Accept(v JobVisitor) { v.VisitTaskGroup(t) } -func (t *TasksDiff) Accept(v JobVisitor) { v.VisitTasks(t) } -func (t *TaskDiff) Accept(v JobVisitor) { v.VisitTask(t) } -func (s *ServicesDiff) Accept(v JobVisitor) { v.VisitServices(s) } -func (s *ServiceDiff) Accept(v JobVisitor) { v.VisitService(s) } -func (s *ServiceChecksDiff) Accept(v JobVisitor) { v.VisitServiceChecks(s) } -func (s *ServiceCheckDiff) Accept(v JobVisitor) { v.VisitServiceCheck(s) } -func (t *TaskArtifactsDiff) Accept(v JobVisitor) { v.VisitTaskArtifactsDiff(t) } -func (t *TaskArtifactDiff) Accept(v JobVisitor) { v.VisitTaskArtifactDiff(t) } -func (r *ResourcesDiff) Accept(v JobVisitor) { v.VisitResources(r) } -func (n *NetworkResourcesDiff) Accept(v JobVisitor) { v.VisitNetworkResources(n) } -func (n *NetworkResourceDiff) Accept(v JobVisitor) { v.VisitNetworkResource(n) } -func (p *PortsDiff) Accept(v JobVisitor) { v.VisitPorts(p) } -func (p *PrimitiveStructDiff) Accept(v JobVisitor) { v.VisitPrimitiveStruct(p) } -func (f *FieldDiff) Accept(v JobVisitor) { v.VisitField(f) } -func (s *StringSetDiff) Accept(v JobVisitor) { v.VisitStringSet(s) } -func (s *StringMapDiff) Accept(v JobVisitor) { v.VisitStringMap(s) } -func (s *StringValueDelta) Accept(v JobVisitor) { v.VisitStringValueDelta(s) }