diff --git a/pkg/apis/pipeline/v1alpha2/taskrun_types.go b/pkg/apis/pipeline/v1alpha2/taskrun_types.go index a5d64bd1c99..4101b3b56c4 100644 --- a/pkg/apis/pipeline/v1alpha2/taskrun_types.go +++ b/pkg/apis/pipeline/v1alpha2/taskrun_types.go @@ -173,7 +173,7 @@ func (tr *TaskRunStatus) SetCondition(newCond *apis.Condition) { } } -// StepState reports the results of running a step in the Task. +// StepState reports the results of running a step in a Task. type StepState struct { corev1.ContainerState Name string `json:"name,omitempty"` @@ -181,10 +181,12 @@ type StepState struct { ImageID string `json:"imageID,omitempty"` } -// SidecarState reports the results of sidecar in the Task. +// SidecarState reports the results of running a sidecar in a Task. type SidecarState struct { - Name string `json:"name,omitempty"` - ImageID string `json:"imageID,omitempty"` + corev1.ContainerState + Name string `json:"name,omitempty"` + ContainerName string `json:"container,omitempty"` + ImageID string `json:"imageID,omitempty"` } // CloudEventDelivery is the target of a cloud event along with the state of diff --git a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go index 3e79cb420bf..a7399d8a03c 100644 --- a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go @@ -920,6 +920,7 @@ func (in *PipelineTaskRun) DeepCopy() *PipelineTaskRun { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SidecarState) DeepCopyInto(out *SidecarState) { *out = *in + in.ContainerState.DeepCopyInto(&out.ContainerState) return } @@ -1402,7 +1403,9 @@ func (in *TaskRunStatusFields) DeepCopyInto(out *TaskRunStatusFields) { if in.Sidecars != nil { in, out := &in.Sidecars, &out.Sidecars *out = make([]SidecarState, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } diff --git a/pkg/pod/entrypoint.go b/pkg/pod/entrypoint.go index 24197861fda..aa0a98313be 100644 --- a/pkg/pod/entrypoint.go +++ b/pkg/pod/entrypoint.go @@ -194,7 +194,7 @@ func StopSidecars(nopImage string, kubeclient kubernetes.Interface, pod corev1.P // An injected sidecar container might not have the // "sidecar-" prefix, so we can't just look for that // prefix. - if !isContainerStep(s.Name) && s.State.Running != nil { + if !IsContainerStep(s.Name) && s.State.Running != nil { for j, c := range newPod.Spec.Containers { if c.Name == s.Name && c.Image != nopImage { updated = true @@ -212,9 +212,21 @@ func StopSidecars(nopImage string, kubeclient kubernetes.Interface, pod corev1.P return nil } +// IsSidecarStatusRunning determines if any SidecarStatus on a TaskRun +// is still running. +func IsSidecarStatusRunning(tr *v1alpha1.TaskRun) bool { + for _, sidecar := range tr.Status.Sidecars { + if sidecar.Terminated == nil { + return true + } + } + + return false +} + // isContainerStep returns true if the container name indicates that it // represents a step. -func isContainerStep(name string) bool { return strings.HasPrefix(name, stepPrefix) } +func IsContainerStep(name string) bool { return strings.HasPrefix(name, stepPrefix) } // isContainerSidecar returns true if the container name indicates that it // represents a sidecar. @@ -225,4 +237,4 @@ func trimStepPrefix(name string) string { return strings.TrimPrefix(name, stepPr // trimSidecarPrefix returns the container name, stripped of its sidecar // prefix. -func trimSidecarPrefix(name string) string { return strings.TrimPrefix(name, sidecarPrefix) } +func TrimSidecarPrefix(name string) string { return strings.TrimPrefix(name, sidecarPrefix) } diff --git a/pkg/pod/status.go b/pkg/pod/status.go index 02ff4769abe..e8223d31798 100644 --- a/pkg/pod/status.go +++ b/pkg/pod/status.go @@ -84,7 +84,7 @@ func SidecarsReady(podStatus corev1.PodStatus) bool { // An injected sidecar might not have the "sidecar-" prefix, so // we can't just look for that prefix, we need to look at any // non-step container. - if isContainerStep(s.Name) { + if IsContainerStep(s.Name) { continue } if s.State.Running != nil && s.Ready { @@ -112,7 +112,6 @@ func MakeTaskRunStatus(tr v1alpha1.TaskRun, pod *corev1.Pod, taskSpec v1alpha1.T } trs.PodName = pod.Name - trs.Steps = []v1alpha1.StepState{} trs.Sidecars = []v1alpha1.SidecarState{} logger, _ := logging.NewLogger("", "status") @@ -121,7 +120,7 @@ func MakeTaskRunStatus(tr v1alpha1.TaskRun, pod *corev1.Pod, taskSpec v1alpha1.T }() for _, s := range pod.Status.ContainerStatuses { - if isContainerStep(s.Name) { + if IsContainerStep(s.Name) { if s.State.Terminated != nil && len(s.State.Terminated.Message) != 0 { msg := s.State.Terminated.Message r, err := termination.ParseMessage(msg) @@ -158,8 +157,10 @@ func MakeTaskRunStatus(tr v1alpha1.TaskRun, pod *corev1.Pod, taskSpec v1alpha1.T }) } else if isContainerSidecar(s.Name) { trs.Sidecars = append(trs.Sidecars, v1alpha1.SidecarState{ - Name: trimSidecarPrefix(s.Name), - ImageID: s.ImageID, + ContainerState: *s.State.DeepCopy(), + Name: TrimSidecarPrefix(s.Name), + ContainerName: s.Name, + ImageID: s.ImageID, }) } } @@ -196,6 +197,7 @@ func updateCompletedTaskRun(trs *v1alpha1.TaskRunStatus, pod *corev1.Pod) { Message: "All Steps have completed executing", }) } + // update tr completed time trs.CompletionTime = &metav1.Time{Time: time.Now()} } @@ -235,7 +237,7 @@ func updateIncompleteTaskRun(trs *v1alpha1.TaskRunStatus, pod *corev1.Pod) { func DidTaskRunFail(pod *corev1.Pod) bool { f := pod.Status.Phase == corev1.PodFailed for _, s := range pod.Status.ContainerStatuses { - if isContainerStep(s.Name) { + if IsContainerStep(s.Name) { if s.State.Terminated != nil { f = f || s.State.Terminated.ExitCode != 0 || isOOMKilled(s) } @@ -247,7 +249,7 @@ func DidTaskRunFail(pod *corev1.Pod) bool { func areStepsComplete(pod *corev1.Pod) bool { stepsComplete := len(pod.Status.ContainerStatuses) > 0 && pod.Status.Phase == corev1.PodRunning for _, s := range pod.Status.ContainerStatuses { - if isContainerStep(s.Name) { + if IsContainerStep(s.Name) { if s.State.Terminated == nil { stepsComplete = false } @@ -287,7 +289,7 @@ func getFailureMessage(pod *corev1.Pod) string { } for _, s := range pod.Status.ContainerStatuses { - if isContainerStep(s.Name) { + if IsContainerStep(s.Name) { if s.State.Terminated != nil { if isOOMKilled(s) { return oomKilled diff --git a/pkg/pod/status_test.go b/pkg/pod/status_test.go index 9215e116ca8..310867a42c6 100644 --- a/pkg/pod/status_test.go +++ b/pkg/pod/status_test.go @@ -491,8 +491,112 @@ func TestMakeTaskRunStatus(t *testing.T) { ContainerName: "step-running-step", }}, Sidecars: []v1alpha1.SidecarState{{ - Name: "running", - ImageID: "image-id", + ContainerState: corev1.ContainerState{ + Running: &corev1.ContainerStateRunning{}, + }, + Name: "running", + ImageID: "image-id", + ContainerName: "sidecar-running", + }}, + }, + }, + }, { + desc: "with-sidecar-waiting", + podStatus: corev1.PodStatus{ + Phase: corev1.PodRunning, + ContainerStatuses: []corev1.ContainerStatus{{ + Name: "step-waiting-step", + State: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "PodInitializing", + Message: "PodInitializing", + }, + }, + }, { + Name: "sidecar-waiting", + ImageID: "image-id", + State: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "PodInitializing", + Message: "PodInitializing", + }, + }, + Ready: true, + }}, + }, + want: v1alpha1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{conditionRunning}, + }, + TaskRunStatusFields: v1alpha1.TaskRunStatusFields{ + Steps: []v1alpha1.StepState{{ + ContainerState: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "PodInitializing", + Message: "PodInitializing", + }, + }, + Name: "waiting-step", + ContainerName: "step-waiting-step", + }}, + Sidecars: []v1alpha1.SidecarState{{ + ContainerState: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "PodInitializing", + Message: "PodInitializing", + }, + }, + Name: "waiting", + ImageID: "image-id", + ContainerName: "sidecar-waiting", + }}, + }, + }, + }, { + desc: "with-sidecar-terminated", + podStatus: corev1.PodStatus{ + Phase: corev1.PodRunning, + ContainerStatuses: []corev1.ContainerStatus{{ + Name: "step-running-step", + State: corev1.ContainerState{ + Running: &corev1.ContainerStateRunning{}, + }, + }, { + Name: "sidecar-error", + ImageID: "image-id", + State: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + ExitCode: 1, + Reason: "Error", + Message: "Error", + }, + }, + Ready: true, + }}, + }, + want: v1alpha1.TaskRunStatus{ + Status: duckv1beta1.Status{ + Conditions: []apis.Condition{conditionRunning}, + }, + TaskRunStatusFields: v1alpha1.TaskRunStatusFields{ + Steps: []v1alpha1.StepState{{ + ContainerState: corev1.ContainerState{ + Running: &corev1.ContainerStateRunning{}, + }, + Name: "running-step", + ContainerName: "step-running-step", + }}, + Sidecars: []v1alpha1.SidecarState{{ + ContainerState: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + ExitCode: 1, + Reason: "Error", + Message: "Error", + }, + }, + Name: "error", + ImageID: "image-id", + ContainerName: "sidecar-error", }}, }, }, diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index 526a7e459b9..8e6395fa146 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -127,6 +127,13 @@ func (c *Reconciler) Reconcile(ctx context.Context, key string) error { pod, err := c.KubeClientSet.CoreV1().Pods(tr.Namespace).Get(tr.Status.PodName, metav1.GetOptions{}) if err == nil { err = podconvert.StopSidecars(c.Images.NopImage, c.KubeClientSet, *pod) + if err == nil { + // Check if any SidecarStatuses are still shown as Running after stopping + // Sidecars. If any Running, update SidecarStatuses based on Pod ContainerStatuses. + if podconvert.IsSidecarStatusRunning(tr) { + err = updateStoppedSidecarStatus(pod, tr, c) + } + } } else if errors.IsNotFound(err) { return merr.ErrorOrNil() } @@ -598,3 +605,33 @@ func getLabelSelector(tr *v1alpha1.TaskRun) string { } return strings.Join(labels, ",") } + +// updateStoppedSidecarStatus updates SidecarStatus for sidecars that were +// terminated by nop image +func updateStoppedSidecarStatus(pod *corev1.Pod, tr *v1alpha1.TaskRun, c *Reconciler) error { + tr.Status.Sidecars = []v1alpha1.SidecarState{} + for _, s := range pod.Status.ContainerStatuses { + if !podconvert.IsContainerStep(s.Name) { + lastTerminatedState := s.LastTerminationState.Terminated + sidecarTerminated := corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + ExitCode: lastTerminatedState.ExitCode, + Reason: "Completed", + Message: "Sidecar container successfully stopped by nop image", + StartedAt: lastTerminatedState.StartedAt, + FinishedAt: lastTerminatedState.FinishedAt, + ContainerID: lastTerminatedState.ContainerID, + }, + } + + tr.Status.Sidecars = append(tr.Status.Sidecars, v1alpha1.SidecarState{ + ContainerState: *sidecarTerminated.DeepCopy(), + Name: podconvert.TrimSidecarPrefix(s.Name), + ContainerName: s.Name, + ImageID: s.ImageID, + }) + } + } + _, err := c.updateStatus(tr) + return err +} diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index a81bdcac8dc..c6c54f87ccd 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -99,6 +99,13 @@ var ( ), )) clustertask = tb.ClusterTask("test-cluster-task", tb.ClusterTaskSpec(simpleStep)) + taskSidecar = tb.Task("test-task-sidecar", "foo", tb.TaskSpec( + tb.Sidecar("sidecar", "image-id"), + )) + taskMultipleSidecars = tb.Task("test-task-sidecar", "foo", tb.TaskSpec( + tb.Sidecar("sidecar", "image-id"), + tb.Sidecar("sidecar2", "image-id"), + )) outputTask = tb.Task("test-output-task", "foo", tb.TaskSpec( simpleStep, tb.TaskInputs( @@ -1145,7 +1152,7 @@ func TestReconcilePodFetchError(t *testing.T) { return true, nil, errors.New("induce failure fetching pods") }) - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", taskRun.Namespace, taskRun.Name)); err == nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err == nil { t.Fatal("expected error when reconciling a Task for which we couldn't get the corresponding Build Pod but got nil") } } @@ -1196,7 +1203,7 @@ func TestReconcilePodUpdateStatus(t *testing.T) { c := testAssets.Controller clients := testAssets.Clients - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", taskRun.Namespace, taskRun.Name)); err != nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { t.Fatalf("Unexpected error when Reconcile() : %v", err) } newTr, err := clients.Pipeline.TektonV1alpha1().TaskRuns(taskRun.Namespace).Get(taskRun.Name, metav1.GetOptions{}) @@ -1219,7 +1226,7 @@ func TestReconcilePodUpdateStatus(t *testing.T) { if _, err := clients.Kube.CoreV1().Pods(taskRun.Namespace).UpdateStatus(pod); err != nil { t.Errorf("Unexpected error while updating build: %v", err) } - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", taskRun.Namespace, taskRun.Name)); err != nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { t.Fatalf("Unexpected error when Reconcile(): %v", err) } @@ -1259,7 +1266,7 @@ func TestReconcileOnCompletedTaskRun(t *testing.T) { c := testAssets.Controller clients := testAssets.Clients - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", taskRun.Namespace, taskRun.Name)); err != nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { t.Fatalf("Unexpected error when reconciling completed TaskRun : %v", err) } newTr, err := clients.Pipeline.TektonV1alpha1().TaskRuns(taskRun.Namespace).Get(taskRun.Name, metav1.GetOptions{}) @@ -1289,7 +1296,7 @@ func TestReconcileOnCancelledTaskRun(t *testing.T) { c := testAssets.Controller clients := testAssets.Clients - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", taskRun.Namespace, taskRun.Name)); err != nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { t.Fatalf("Unexpected error when reconciling completed TaskRun : %v", err) } newTr, err := clients.Pipeline.TektonV1alpha1().TaskRuns(taskRun.Namespace).Get(taskRun.Name, metav1.GetOptions{}) @@ -1377,7 +1384,7 @@ func TestReconcileTimeouts(t *testing.T) { c := testAssets.Controller clients := testAssets.Clients - if err := c.Reconciler.Reconcile(context.Background(), fmt.Sprintf("%s/%s", tc.taskRun.Namespace, tc.taskRun.Name)); err != nil { + if err := c.Reconciler.Reconcile(context.Background(), getRunName(tc.taskRun)); err != nil { t.Fatalf("Unexpected error when reconciling completed TaskRun : %v", err) } newTr, err := clients.Pipeline.TektonV1alpha1().TaskRuns(tc.taskRun.Namespace).Get(tc.taskRun.Name, metav1.GetOptions{}) @@ -1881,3 +1888,120 @@ func TestUpdateTaskRunResourceResult_Errors(t *testing.T) { }) } } + +func TestReconcile_Single_SidecarState(t *testing.T) { + runningState := corev1.ContainerStateRunning{StartedAt: metav1.Time{Time: time.Now()}} + taskRun := tb.TaskRun("test-taskrun-sidecars", "foo", + tb.TaskRunSpec( + tb.TaskRunTaskRef(taskSidecar.Name), + ), + tb.TaskRunStatus( + tb.SidecarState( + tb.SidecarStateName("sidecar"), + tb.SidecarStateImageID("image-id"), + tb.SidecarStateContainerName("sidecar-sidecar"), + tb.SetSidecarStateRunning(runningState), + ), + ), + ) + + d := test.Data{ + TaskRuns: []*v1alpha1.TaskRun{taskRun}, + Tasks: []*v1alpha1.Task{taskSidecar}, + } + + testAssets, cancel := getTaskRunController(t, d) + defer cancel() + clients := testAssets.Clients + + if err := testAssets.Controller.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { + t.Errorf("expected no error reconciling valid TaskRun but got %v", err) + } + + getTaskRun, err := clients.Pipeline.TektonV1alpha1().TaskRuns(taskRun.Namespace).Get(taskRun.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("Expected completed TaskRun %s to exist but instead got error when getting it: %v", taskRun.Name, err) + } + + expected := v1alpha1.SidecarState{ + Name: "sidecar", + ImageID: "image-id", + ContainerName: "sidecar-sidecar", + ContainerState: corev1.ContainerState{ + Running: &runningState, + }, + } + + if c := cmp.Diff(expected, getTaskRun.Status.Sidecars[0]); c != "" { + t.Errorf("TestReconcile_Single_SidecarState (-want, +got): %s", c) + } +} + +func TestReconcile_Multiple_SidecarStates(t *testing.T) { + runningState := corev1.ContainerStateRunning{StartedAt: metav1.Time{Time: time.Now()}} + waitingState := corev1.ContainerStateWaiting{Reason: "PodInitializing"} + taskRun := tb.TaskRun("test-taskrun-sidecars", "foo", + tb.TaskRunSpec( + tb.TaskRunTaskRef(taskMultipleSidecars.Name), + ), + tb.TaskRunStatus( + tb.SidecarState( + tb.SidecarStateName("sidecar1"), + tb.SidecarStateImageID("image-id"), + tb.SidecarStateContainerName("sidecar-sidecar1"), + tb.SetSidecarStateRunning(runningState), + ), + ), + tb.TaskRunStatus( + tb.SidecarState( + tb.SidecarStateName("sidecar2"), + tb.SidecarStateImageID("image-id"), + tb.SidecarStateContainerName("sidecar-sidecar2"), + tb.SetSidecarStateWaiting(waitingState), + ), + ), + ) + + d := test.Data{ + TaskRuns: []*v1alpha1.TaskRun{taskRun}, + Tasks: []*v1alpha1.Task{taskMultipleSidecars}, + } + + testAssets, cancel := getTaskRunController(t, d) + defer cancel() + clients := testAssets.Clients + + if err := testAssets.Controller.Reconciler.Reconcile(context.Background(), getRunName(taskRun)); err != nil { + t.Errorf("expected no error reconciling valid TaskRun but got %v", err) + } + + getTaskRun, err := clients.Pipeline.TektonV1alpha1().TaskRuns(taskRun.Namespace).Get(taskRun.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("Expected completed TaskRun %s to exist but instead got error when getting it: %v", taskRun.Name, err) + } + + expected := []v1alpha1.SidecarState{ + { + Name: "sidecar1", + ImageID: "image-id", + ContainerName: "sidecar-sidecar1", + ContainerState: corev1.ContainerState{ + Running: &runningState, + }, + }, + { + Name: "sidecar2", + ImageID: "image-id", + ContainerName: "sidecar-sidecar2", + ContainerState: corev1.ContainerState{ + Waiting: &waitingState, + }, + }, + } + + for i, sc := range getTaskRun.Status.Sidecars { + if c := cmp.Diff(expected[i], sc); c != "" { + t.Errorf("TestReconcile_Multiple_SidecarStates sidecar%d (-want, +got): %s", i+1, c) + } + } +} diff --git a/test/builder/sidecar.go b/test/builder/sidecar.go new file mode 100644 index 00000000000..e177d97a9dd --- /dev/null +++ b/test/builder/sidecar.go @@ -0,0 +1,67 @@ +/* +Copyright 2020 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + corev1 "k8s.io/api/core/v1" +) + +// SidecarStateName sets the name of the Sidecar for the SidecarState. +func SidecarStateName(name string) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.Name = name + } +} + +// SetSidecarStateImageID sets ImageID of Sidecar for SidecarState. +func SidecarStateImageID(imageID string) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.ImageID = imageID + } +} + +// SetSidecarStateImageID sets ImageID of Sidecar for SidecarState. +func SidecarStateContainerName(containerName string) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.ContainerName = containerName + } +} + +// SetSidecarStateTerminated sets Terminated state of a Sidecar. +func SetSidecarStateTerminated(terminated corev1.ContainerStateTerminated) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.ContainerState = corev1.ContainerState{ + Terminated: &terminated, + } + } +} + +// SetSidecarStateRunning sets Running state of a Sidecar. +func SetSidecarStateRunning(running corev1.ContainerStateRunning) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.ContainerState = corev1.ContainerState{ + Running: &running, + } + } +} + +// SetSidecarStateWaiting sets Waiting state of a Sidecar. +func SetSidecarStateWaiting(waiting corev1.ContainerStateWaiting) SidecarStateOp { + return func(s *v1alpha1.SidecarState) { + s.ContainerState = corev1.ContainerState{ + Waiting: &waiting, + } + } +} diff --git a/test/builder/task.go b/test/builder/task.go index ce3f7a83f86..d7652666b25 100644 --- a/test/builder/task.go +++ b/test/builder/task.go @@ -483,20 +483,6 @@ func SetStepStateWaiting(waiting corev1.ContainerStateWaiting) StepStateOp { } } -// SetSidecarStateName sets Name of Sidecar for SidecarState. -func SetSidecarStateName(name string) SidecarStateOp { - return func(s *v1alpha1.SidecarState) { - s.Name = name - } -} - -// SetSidecarStateImageID sets ImageID of Sidecar for SidecarState. -func SetSidecarStateImageID(imageID string) SidecarStateOp { - return func(s *v1alpha1.SidecarState) { - s.ImageID = imageID - } -} - // TaskRunOwnerReference sets the OwnerReference, with specified kind and name, to the TaskRun. func TaskRunOwnerReference(kind, name string, ops ...OwnerReferenceOp) TaskRunOp { return func(tr *v1alpha1.TaskRun) { diff --git a/test/builder/task_test.go b/test/builder/task_test.go index e2e8589c74f..e00fc015516 100644 --- a/test/builder/task_test.go +++ b/test/builder/task_test.go @@ -163,6 +163,7 @@ func TestClusterTask(t *testing.T) { func TestTaskRunWithTaskRef(t *testing.T) { var trueB = true + terminatedState := corev1.ContainerStateTerminated{Reason: "Completed"} taskRun := tb.TaskRun("test-taskrun", "foo", tb.TaskRunOwnerReference("PipelineRun", "test", @@ -203,8 +204,10 @@ func TestTaskRunWithTaskRef(t *testing.T) { tb.StatusCondition(apis.Condition{Type: apis.ConditionSucceeded}), tb.StepState(tb.StateTerminated(127)), tb.SidecarState( - tb.SetSidecarStateName("sidecar"), - tb.SetSidecarStateImageID("ImageID"), + tb.SidecarStateName("sidecar"), + tb.SidecarStateImageID("ImageID"), + tb.SidecarStateContainerName("ContainerName"), + tb.SetSidecarStateTerminated(terminatedState), ), ), ) @@ -285,8 +288,17 @@ func TestTaskRunWithTaskRef(t *testing.T) { Conditions: []apis.Condition{{Type: apis.ConditionSucceeded}}, }, TaskRunStatusFields: v1alpha1.TaskRunStatusFields{ - PodName: "my-pod-name", - Sidecars: []v1alpha2.SidecarState{{Name: "sidecar", ImageID: "ImageID"}}, + PodName: "my-pod-name", + Sidecars: []v1alpha2.SidecarState{{ + Name: "sidecar", + ImageID: "ImageID", + ContainerName: "ContainerName", + ContainerState: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + Reason: "Completed", + }, + }, + }}, Steps: []v1alpha1.StepState{{ContainerState: corev1.ContainerState{ Terminated: &corev1.ContainerStateTerminated{ExitCode: 127}, }}}, diff --git a/test/sidecar_test.go b/test/sidecar_test.go index e65ef9dfc7d..13ec9db66b2 100644 --- a/test/sidecar_test.go +++ b/test/sidecar_test.go @@ -139,6 +139,23 @@ func TestSidecarTaskSupport(t *testing.T) { if !primaryTerminated || !sidecarTerminated { t.Errorf("Either the primary or sidecar containers did not terminate") } + + trCheckSidecarStatus, err := clients.TaskRunClient.Get(sidecarTaskRunName, metav1.GetOptions{}) + if err != nil { + t.Errorf("Error getting TaskRun: %v", err) + } + + sidecarFromStatus := trCheckSidecarStatus.Status.Sidecars[0] + + // Check if Sidecar ContainerName is present for SidecarStatus + if sidecarFromStatus.ContainerName != fmt.Sprintf("sidecar-%s", sidecarContainerName) { + t.Errorf("Sidecar ContainerName should be: %s", sidecarContainerName) + } + + // Check if Terminated status is present for SidecarStatus + if sidecarFromStatus.Terminated == nil { + t.Errorf("TaskRunStatus: Sidecar container has a nil Terminated status but non-nil is expected.") + } }) } }