diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index b2230a8feb3e..9956050cb388 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -1032,7 +1032,7 @@ func TestTaskGroup_UsesConnect(t *testing.T) { }) } -func TestTaskGroup_Validate2(t *testing.T) { +func TestTaskGroup_Validate(t *testing.T) { ci.Parallel(t) tests := []struct { @@ -1406,327 +1406,6 @@ func TestTaskGroup_Validate2(t *testing.T) { } } -func TestTaskGroup_Validate(t *testing.T) { - ci.Parallel(t) - - j := testJob() - tg := &TaskGroup{ - Count: -1, - RestartPolicy: &RestartPolicy{ - Interval: 5 * time.Minute, - Delay: 10 * time.Second, - Attempts: 10, - Mode: RestartPolicyModeDelay, - }, - ReschedulePolicy: &ReschedulePolicy{ - Interval: 5 * time.Minute, - Attempts: 5, - Delay: 5 * time.Second, - }, - } - err := tg.Validate(j) - requireErrors(t, err, - "group name", - "count can't be negative", - "Missing tasks", - ) - - tg = &TaskGroup{ - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{ - Networks: []*NetworkResource{ - { - ReservedPorts: []Port{{Label: "foo", Value: 123}}, - }, - }, - }, - }, - { - Name: "task-b", - Resources: &Resources{ - Networks: []*NetworkResource{ - { - ReservedPorts: []Port{{Label: "foo", Value: 123}}, - }, - }, - }, - }, - }, - } - err = tg.Validate(&Job{}) - expected := `Static port 123 already reserved by task-a:foo` - if !strings.Contains(err.Error(), expected) { - t.Errorf("expected %s but found: %v", expected, err) - } - - tg = &TaskGroup{ - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{ - Networks: []*NetworkResource{ - { - ReservedPorts: []Port{ - {Label: "foo", Value: 123}, - {Label: "bar", Value: 123}, - }, - }, - }, - }, - }, - }, - } - err = tg.Validate(&Job{}) - expected = `Static port 123 already reserved by task-a:foo` - if !strings.Contains(err.Error(), expected) { - t.Errorf("expected %s but found: %v", expected, err) - } - - tg = &TaskGroup{ - Name: "web", - Count: 1, - Tasks: []*Task{ - {Name: "web", Leader: true}, - {Name: "web", Leader: true}, - {}, - }, - RestartPolicy: &RestartPolicy{ - Interval: 5 * time.Minute, - Delay: 10 * time.Second, - Attempts: 10, - Mode: RestartPolicyModeDelay, - }, - ReschedulePolicy: &ReschedulePolicy{ - Interval: 5 * time.Minute, - Attempts: 10, - Delay: 5 * time.Second, - DelayFunction: "constant", - }, - } - - err = tg.Validate(j) - requireErrors(t, err, - "should have an ephemeral disk object", - "2 redefines 'web' from task 1", - "Task 3 missing name", - "Only one task may be marked as leader", - "Task web validation failed", - ) - - tg = &TaskGroup{ - Name: "web", - Count: 1, - Tasks: []*Task{ - {Name: "web", Leader: true}, - }, - Update: DefaultUpdateStrategy.Copy(), - } - j.Type = JobTypeBatch - err = tg.Validate(j) - require.Error(t, err, "does not allow update block") - - tg = &TaskGroup{ - Count: -1, - RestartPolicy: &RestartPolicy{ - Interval: 5 * time.Minute, - Delay: 10 * time.Second, - Attempts: 10, - Mode: RestartPolicyModeDelay, - }, - ReschedulePolicy: &ReschedulePolicy{ - Interval: 5 * time.Minute, - Attempts: 5, - Delay: 5 * time.Second, - }, - } - j.Type = JobTypeSystem - err = tg.Validate(j) - if !strings.Contains(err.Error(), "System jobs should not have a reschedule policy") { - t.Fatalf("err: %s", err) - } - - tg = &TaskGroup{ - Networks: []*NetworkResource{ - { - DynamicPorts: []Port{{"http", 0, 80, ""}}, - }, - }, - Tasks: []*Task{ - { - Resources: &Resources{ - Networks: []*NetworkResource{ - { - DynamicPorts: []Port{{"http", 0, 80, ""}}, - }, - }, - }, - }, - }, - } - err = tg.Validate(j) - require.Contains(t, err.Error(), "Port label http already in use") - - tg = &TaskGroup{ - Volumes: map[string]*VolumeRequest{ - "foo": { - Type: "nothost", - Source: "foo", - }, - }, - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{}, - }, - }, - } - err = tg.Validate(&Job{}) - require.Contains(t, err.Error(), `volume has unrecognized type nothost`) - - tg = &TaskGroup{ - Volumes: map[string]*VolumeRequest{ - "foo": { - Type: "host", - }, - }, - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{}, - }, - }, - } - err = tg.Validate(&Job{}) - require.Contains(t, err.Error(), `volume has an empty source`) - - tg = &TaskGroup{ - Name: "group-a", - Update: &UpdateStrategy{ - Canary: 1, - }, - Volumes: map[string]*VolumeRequest{ - "foo": { - Type: "csi", - PerAlloc: true, - }, - }, - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{}, - }, - }, - } - err = tg.Validate(&Job{}) - require.Contains(t, err.Error(), `volume has an empty source`) - require.Contains(t, err.Error(), `volume cannot be per_alloc when canaries are in use`) - require.Contains(t, err.Error(), `CSI volumes must have an attachment mode`) - require.Contains(t, err.Error(), `CSI volumes must have an access mode`) - - tg = &TaskGroup{ - Volumes: map[string]*VolumeRequest{ - "foo": { - Type: "host", - }, - }, - Tasks: []*Task{ - { - Name: "task-a", - Resources: &Resources{}, - VolumeMounts: []*VolumeMount{ - { - Volume: "", - }, - }, - }, - { - Name: "task-b", - Resources: &Resources{}, - VolumeMounts: []*VolumeMount{ - { - Volume: "foob", - }, - }, - }, - }, - } - err = tg.Validate(&Job{}) - expected = `Task task-a has a volume mount (0) referencing an empty volume` - require.Contains(t, err.Error(), expected) - - expected = `Task task-b has a volume mount (0) referencing undefined volume foob` - require.Contains(t, err.Error(), expected) - - taskA := &Task{Name: "task-a"} - tg = &TaskGroup{ - Name: "group-a", - Services: []*Service{ - { - Name: "service-a", - Provider: "consul", - Checks: []*ServiceCheck{ - { - Name: "check-a", - Type: "tcp", - TaskName: "task-b", - PortLabel: "http", - Interval: time.Duration(1 * time.Second), - Timeout: time.Duration(1 * time.Second), - }, - }, - }, - }, - Tasks: []*Task{taskA}, - } - err = tg.Validate(&Job{}) - expected = `Check check-a invalid: refers to non-existent task task-b` - require.Contains(t, err.Error(), expected) - - tg = &TaskGroup{ - Name: "group-a", - Services: []*Service{ - { - Name: "service-a", - Provider: "nomad", - }, - { - Name: "service-b", - Provider: "consul", - }, - }, - Tasks: []*Task{{Name: "task-a"}}, - } - err = tg.Validate(&Job{}) - expected = "Multiple service providers used: task group services must use the same provider" - require.Contains(t, err.Error(), expected) - - tg = &TaskGroup{ - Name: "group-a", - Services: []*Service{ - { - Name: "service-a", - Provider: "nomad", - }, - }, - Tasks: []*Task{ - { - Name: "task-a", - Services: []*Service{ - { - Name: "service-b", - Provider: "consul", - }, - }, - }, - }, - } - err = tg.Validate(&Job{}) - expected = "Multiple service providers used: task group services must use the same provider" - require.Contains(t, err.Error(), expected) -} - func TestTaskGroupNetwork_Validate(t *testing.T) { ci.Parallel(t)