func TestTemplateContext(t *testing.T) { for _, testcase := range []struct { Test string Task *api.Task Context Context Expected *api.ContainerSpec Err error }{ { Test: "Identity", Task: modifyTask(func(t *api.Task) { t.Spec = api.TaskSpec{ Runtime: &api.TaskSpec_Container{ Container: &api.ContainerSpec{ Env: []string{ "NOTOUCH=dont", }, Mounts: []api.Mount{ { Target: "foo", Source: "bar", }, }, }, }, } }), Expected: &api.ContainerSpec{ Env: []string{ "NOTOUCH=dont", }, Mounts: []api.Mount{ { Target: "foo", Source: "bar", }, }, }, }, { Test: "Env", Task: modifyTask(func(t *api.Task) { t.Spec = api.TaskSpec{ Runtime: &api.TaskSpec_Container{ Container: &api.ContainerSpec{ Labels: map[string]string{ "ContainerLabel": "should-NOT-end-up-as-task", }, Env: []string{ "MYENV=notemplate", "{{.NotExpanded}}=foo", "SERVICE_ID={{.Service.ID}}", "SERVICE_NAME={{.Service.Name}}", "TASK_ID={{.Task.ID}}", "TASK_NAME={{.Task.Name}}", "NODE_ID={{.Node.ID}}", "SERVICE_LABELS={{range $k, $v := .Service.Labels}}{{$k}}={{$v}},{{end}}", }, }, }, } }), Expected: &api.ContainerSpec{ Labels: map[string]string{ "ContainerLabel": "should-NOT-end-up-as-task", }, Env: []string{ "MYENV=notemplate", "{{.NotExpanded}}=foo", "SERVICE_ID=serviceID", "SERVICE_NAME=serviceName", "TASK_ID=taskID", "TASK_NAME=serviceName.10.taskID", "NODE_ID=nodeID", "SERVICE_LABELS=ServiceLabelOneKey=service-label-one-value,ServiceLabelTwoKey=service-label-two-value,com.example.ServiceLabelThreeKey=service-label-three-value,", }, }, }, { Test: "Mount", Task: modifyTask(func(t *api.Task) { t.Spec = api.TaskSpec{ Runtime: &api.TaskSpec_Container{ Container: &api.ContainerSpec{ Mounts: []api.Mount{ { Source: "bar-{{.Node.ID}}-{{.Task.Name}}", Target: "foo-{{.Service.ID}}-{{.Service.Name}}", }, { Source: "bar-{{.Node.ID}}-{{.Service.Name}}", Target: "foo-{{.Task.Slot}}-{{.Task.ID}}", }, }, }, }, } }), Expected: &api.ContainerSpec{ Mounts: []api.Mount{ { Source: "bar-nodeID-serviceName.10.taskID", Target: "foo-serviceID-serviceName", }, { Source: "bar-nodeID-serviceName", Target: "foo-10-taskID", }, }, }, }, { Test: "Hostname", Task: modifyTask(func(t *api.Task) { t.Spec = api.TaskSpec{ Runtime: &api.TaskSpec_Container{ Container: &api.ContainerSpec{ Hostname: "myhost-{{.Task.Slot}}", }, }, } }), Expected: &api.ContainerSpec{ Hostname: "myhost-10", }, }, } { t.Run(testcase.Test, func(t *testing.T) { spec, err := ExpandContainerSpec(testcase.Task) if err != nil { if testcase.Err == nil { t.Fatalf("unexpected error: %v", err) } else { if err != testcase.Err { t.Fatalf("unexpected error: %v != %v", err, testcase.Err) } } } assert.Equal(t, testcase.Expected, spec) for k, v := range testcase.Task.Annotations.Labels { // make sure that that task.annotations.labels didn't make an appearance. visitAllTemplatedFields(spec, func(s string) { if strings.Contains(s, k) || strings.Contains(s, v) { t.Fatalf("string value from task labels found in expanded spec: %q or %q found in %q, on %#v", k, v, s, spec) } }) } }) } }