From 4d5d886b7deee5313b2b2111a5378fade22aff88 Mon Sep 17 00:00:00 2001 From: Christie Wilson Date: Thu, 11 Oct 2018 09:30:16 -0700 Subject: [PATCH] Add condition status to PipelineRun PipelineRun status will be based on the condition of the TaskRuns which it has created, for #61. If any TaskRuns have failed, the PipelineRun has failed. If all are successful, it is successful. If any are in progress, it is in progress. This is assuming a linear Pipeline, we will have to tweak this a bit when we implement the graph (for #65) --- .../pipeline/v1alpha1/pipelinerun_types.go | 49 ++--- pkg/apis/pipeline/v1alpha1/taskrun_types.go | 8 + .../v1alpha1/zz_generated.deepcopy.go | 19 +- .../v1alpha1/pipelinerun/pipelinerun.go | 23 ++- .../v1alpha1/pipelinerun/pipelinerun_test.go | 17 +- .../pipelinerun/resources/pipelinestate.go | 72 ++++++- .../resources/pipelinestate_test.go | 184 +++++++++++------- test/pipelinerun_test.go | 35 ++-- 8 files changed, 257 insertions(+), 150 deletions(-) diff --git a/pkg/apis/pipeline/v1alpha1/pipelinerun_types.go b/pkg/apis/pipeline/v1alpha1/pipelinerun_types.go index 96fd4a325d8..3ef0347c3a7 100644 --- a/pkg/apis/pipeline/v1alpha1/pipelinerun_types.go +++ b/pkg/apis/pipeline/v1alpha1/pipelinerun_types.go @@ -17,7 +17,7 @@ limitations under the License. package v1alpha1 import ( - corev1 "k8s.io/api/core/v1" + duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -71,7 +71,22 @@ type PipelineRunStatus struct { // If there is no version, that means use latest // +optional ResourceVersion []PipelineResourceVersion `json:"resourceVersion,omitempty"` - Conditions []PipelineRunCondition `json:"conditions"` + Conditions duckv1alpha1.Conditions `json:"conditions"` +} + +var pipelineRunCondSet = duckv1alpha1.NewBatchConditionSet() + +// GetCondition returns the Condition matching the given type. +func (pr *PipelineRunStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition { + return pipelineRunCondSet.Manage(pr).GetCondition(t) +} + +// SetCondition sets the condition, unsetting previous conditions with the same +// type as necessary. +func (pr *PipelineRunStatus) SetCondition(newCond *duckv1alpha1.Condition) { + if newCond != nil { + pipelineRunCondSet.Manage(pr).SetCondition(*newCond) + } } // +genclient @@ -106,33 +121,3 @@ type PipelineRunList struct { type PipelineTaskRun struct { Name string `json:"name"` } - -// PipelineRunConditionType indicates the status of the execution of the PipelineRun. -type PipelineRunConditionType string - -const ( - // PipelineRunConditionTypeStarted indicates whether or not the PipelineRun - // has started actually executing. - PipelineRunConditionTypeStarted PipelineRunConditionType = "Started" - - //PipelineRunConditionTypeCompleted indicates whether or not the PipelineRun - // has finished executing. - PipelineRunConditionTypeCompleted PipelineRunConditionType = "Completed" - - // PipelineRunConditionTypeSucceeded indicates whether or not the PipelineRun - // was successful. - PipelineRunConditionTypeSucceeded PipelineRunConditionType = "Successful" -) - -// PipelineRunCondition holds a Condition that the PipelineRun has entered into while being executed. -type PipelineRunCondition struct { - Type PipelineRunConditionType `json:"type"` - - Status corev1.ConditionStatus `json:"status"` - - LastTransitionTime metav1.Time `json:"lastTransitionTime"` - // +optional - Reason string `json:"reason,omitempty"` - // +optional - Message string `json:"message,omitempty"` -} diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_types.go b/pkg/apis/pipeline/v1alpha1/taskrun_types.go index f1e8490190a..e009166e0c7 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_types.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_types.go @@ -81,6 +81,14 @@ func (tr *TaskRunStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha return taskRunCondSet.Manage(tr).GetCondition(t) } +// SetCondition sets the condition, unsetting previous conditions with the same +// type as necessary. +func (bs *TaskRunStatus) SetCondition(newCond *duckv1alpha1.Condition) { + if newCond != nil { + taskRunCondSet.Manage(bs).SetCondition(*newCond) + } +} + // StepRun reports the results of running a step in the Task. Each // task has the potential to succeed or fail (based on the exit code) // and produces logs. diff --git a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go index 2cf4767e656..283012d57df 100644 --- a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go @@ -514,23 +514,6 @@ func (in *PipelineRun) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PipelineRunCondition) DeepCopyInto(out *PipelineRunCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PipelineRunCondition. -func (in *PipelineRunCondition) DeepCopy() *PipelineRunCondition { - if in == nil { - return nil - } - out := new(PipelineRunCondition) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineRunList) DeepCopyInto(out *PipelineRunList) { *out = *in @@ -598,7 +581,7 @@ func (in *PipelineRunStatus) DeepCopyInto(out *PipelineRunStatus) { } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]PipelineRunCondition, len(*in)) + *out = make(duck_v1alpha1.Conditions, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go index 56d47a4a041..5fbbd89d6a8 100644 --- a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go @@ -141,7 +141,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er fmt.Sprintf("%s/%s", pr.Namespace, pr.Spec.PipelineRef.Name)) return nil } - pipelineTaskRuns, err := resources.GetPipelineState( + state, err := resources.GetPipelineState( func(namespace, name string) (*v1alpha1.Task, error) { return c.taskLister.Tasks(namespace).Get(name) }, @@ -153,18 +153,17 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er if err != nil { return fmt.Errorf("error getting Tasks for Pipeline %s, Pipeline may be invalid!: %s", p.Name, err) } - prtr := resources.GetNextTask(pipelineTaskRuns) - prtr.TaskRun, err = c.createTaskRun(prtr.Task, prtr.TaskRunName, pr) - if err != nil { - return fmt.Errorf("error creating TaskRun called %s for PipelineTask %s from PipelineRun %s: %s", prtr.TaskRunName, prtr.PipelineTask.Name, pr.Name, err) + prtr := resources.GetNextTask(pr.Name, state, c.Logger) + if prtr != nil { + c.Logger.Infof("Creating a new TaskRun object %s", prtr.TaskRunName) + prtr.TaskRun, err = c.createTaskRun(prtr.Task, prtr.TaskRunName, pr) + if err != nil { + return fmt.Errorf("error creating TaskRun called %s for PipelineTask %s from PipelineRun %s: %s", prtr.TaskRunName, prtr.PipelineTask.Name, pr.Name, err) + } } - // TODO fetch the taskruns status for this pipeline run. - // get all taskruns for all tasks - - // if any either dont exist yet or are themselves unknown, status is unknown - // if the status of any is failed, then this pipeline run is failed and we should stop trying to run more - + pr.Status.SetCondition(resources.GetPipelineConditionStatus(pr.Name, state, c.Logger)) + c.Logger.Infof("PipelineRun %s status is being set to %s", pr.Name, pr.Status) return nil } @@ -185,7 +184,7 @@ func (c *Reconciler) createTaskRun(t *v1alpha1.Task, trName string, pr *v1alpha1 func (c *Reconciler) updateStatus(pr *v1alpha1.PipelineRun) (*v1alpha1.PipelineRun, error) { newPr, err := c.pipelineRunLister.PipelineRuns(pr.Namespace).Get(pr.Name) if err != nil { - return nil, err + return nil, fmt.Errorf("Error getting PipelineRun %s when updating status: %s", pr.Name, err) } if !reflect.DeepEqual(newPr.Status, pr.Status) { newPr.Status = pr.Status diff --git a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go index 0420a74a633..f7d1ab83b89 100644 --- a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go @@ -157,7 +157,21 @@ type testData struct { } func seedTestData(d testData) (*fakepipelineclientset.Clientset, informersv1alpha1.PipelineRunInformer, informersv1alpha1.PipelineInformer, informersv1alpha1.TaskRunInformer, informersv1alpha1.TaskInformer) { - pipelineClient := fakepipelineclientset.NewSimpleClientset() + objs := []runtime.Object{} + for _, pr := range d.prs { + objs = append(objs, pr) + } + for _, p := range d.ps { + objs = append(objs, p) + } + for _, tr := range d.trs { + objs = append(objs, tr) + } + for _, t := range d.ts { + objs = append(objs, t) + } + pipelineClient := fakepipelineclientset.NewSimpleClientset(objs...) + sharedInfomer := informers.NewSharedInformerFactory(pipelineClient, 0) pipelineRunsInformer := sharedInfomer.Pipeline().V1alpha1().PipelineRuns() pipelineInformer := sharedInfomer.Pipeline().V1alpha1().Pipelines() @@ -170,7 +184,6 @@ func seedTestData(d testData) (*fakepipelineclientset.Clientset, informersv1alph for _, p := range d.ps { pipelineInformer.Informer().GetIndexer().Add(p) } - for _, tr := range d.trs { taskRunInformer.Informer().GetIndexer().Add(tr) } diff --git a/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate.go b/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate.go index ad5ea85c2af..d881c89568a 100644 --- a/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate.go +++ b/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate.go @@ -20,30 +20,37 @@ import ( "fmt" duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" + "go.uber.org/zap" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "github.com/knative/build-pipeline/pkg/apis/pipeline/v1alpha1" ) -// GetNextTask returns the first Task in pipelineTaskRuns that does -// not have a corresponding TaskRun and can run. -func GetNextTask(pipelineTaskRuns []*PipelineRunTaskRun) *PipelineRunTaskRun { - for _, prtr := range pipelineTaskRuns { +// GetNextTask returns the next Task for which a TaskRun should be created, +// or nil if no TaskRun should be created. +func GetNextTask(prName string, state []*PipelineRunTaskRun, logger *zap.SugaredLogger) *PipelineRunTaskRun { + for _, prtr := range state { if prtr.TaskRun != nil { - switch s := prtr.TaskRun.Status.GetCondition(duckv1alpha1.ConditionSucceeded); s.Status { - // if any of the TaskRuns failed, there is no new TaskRun to start + c := prtr.TaskRun.Status.GetCondition(duckv1alpha1.ConditionSucceeded) + if c == nil { + logger.Infof("TaskRun %s doesn't have a condition so it is just starting and we shouldn't start more for PipelineRun %s", prtr.TaskRunName, prName) + return nil + } + switch c.Status { case corev1.ConditionFalse: + logger.Infof("TaskRun %s has failed; we don't need to run PipelineRun %s", prtr.TaskRunName, prName) return nil - // if the current TaskRun is currently running, don't start another one case corev1.ConditionUnknown: + logger.Infof("TaskRun %s is still running so we shouldn't start more for PipelineRun %s", prtr.TaskRunName, prName) return nil } - // otherwise the TaskRun has finished successfully, so we should move on } else if canTaskRun(prtr.PipelineTask) { + logger.Infof("TaskRun %s should be started for PipelineRun %s", prtr.TaskRunName, prName) return prtr } } + logger.Infof("No TaskRuns to start for PipelineRun %s", prName) return nil } @@ -105,3 +112,52 @@ func GetPipelineState(getTask GetTask, getTaskRun GetTaskRun, p *v1alpha1.Pipeli func getTaskRunName(prName string, pt *v1alpha1.PipelineTask) string { return fmt.Sprintf("%s-%s", prName, pt.Name) } + +// GetPipelineConditionStatus will return the Condition that the PipelineRun prName should be +// updated with, based on the status of the TaskRuns in state. +func GetPipelineConditionStatus(prName string, state []*PipelineRunTaskRun, logger *zap.SugaredLogger) *duckv1alpha1.Condition { + allFinished := true + for _, prtr := range state { + if prtr.TaskRun == nil { + logger.Infof("TaskRun %s doesn't have a Status, so PipelineRun %s isn't finished", prtr.TaskRunName, prName) + allFinished = false + break + } + c := prtr.TaskRun.Status.GetCondition(duckv1alpha1.ConditionSucceeded) + if c == nil { + logger.Infof("TaskRun %s doens't have a condition, so PipelineRun %s isn't finished", prtr.TaskRunName, prName) + allFinished = false + break + } + // If any TaskRuns have failed, we should halt execution and consider the run failed + if c.Status == corev1.ConditionFalse { + logger.Infof("TaskRun %s has failed, so PipelineRun %s has failed", prtr.TaskRunName, prName) + return &duckv1alpha1.Condition{ + Type: duckv1alpha1.ConditionSucceeded, + Status: corev1.ConditionFalse, + Reason: "Failed", + Message: fmt.Sprintf("TaskRun %s for Task %s has failed", prtr.TaskRun.Name, prtr.Task.Name), + } + } + if c.Status != corev1.ConditionTrue { + logger.Infof("TaskRun %s is still running so PipelineRun %s is still running", prtr.TaskRunName, prName) + allFinished = false + } + } + if !allFinished { + logger.Infof("PipelineRun %s still has running TaskRuns so it isn't yet done", prName) + return &duckv1alpha1.Condition{ + Type: duckv1alpha1.ConditionSucceeded, + Status: corev1.ConditionUnknown, + Reason: "Running", + Message: "Not all Tasks in the Pipeline have finished executing", + } + } + logger.Infof("All TaskRuns have finished for PipelineRun %s so it has finished", prName) + return &duckv1alpha1.Condition{ + Type: duckv1alpha1.ConditionSucceeded, + Status: corev1.ConditionTrue, + Reason: "Finished", + Message: "All Tasks have completed executing", + } +} diff --git a/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate_test.go b/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate_test.go index 9ae8be7984b..0ae1b1c9b93 100644 --- a/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate_test.go +++ b/pkg/reconciler/v1alpha1/pipelinerun/resources/pipelinestate_test.go @@ -20,6 +20,8 @@ import ( "fmt" "testing" + "go.uber.org/zap" + "github.com/google/go-cmp/cmp" duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" corev1 "k8s.io/api/core/v1" @@ -106,73 +108,74 @@ func newTaskRun(tr v1alpha1.TaskRun) *v1alpha1.TaskRun { } } +var noneStartedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: nil, +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: nil, +}} +var oneStartedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: makeStarted(trs[0]), +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: nil, +}} +var oneFinishedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: makeSucceeded(trs[0]), +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: nil, +}} +var oneFailedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: makeFailed(trs[0]), +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: nil, +}} +var firstFinishedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: makeSucceeded(trs[0]), +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: nil, +}} +var allFinishedState = []*PipelineRunTaskRun{{ + Task: task, + PipelineTask: &pts[0], + TaskRunName: "pipelinerun-mytask1", + TaskRun: makeSucceeded(trs[0]), +}, { + Task: task, + PipelineTask: &pts[1], + TaskRunName: "pipelinerun-mytask2", + TaskRun: makeSucceeded(trs[0]), +}} + func TestGetNextTask_NoneStarted(t *testing.T) { - noneStartedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: nil, - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: nil, - }} - oneStartedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: makeStarted(trs[0]), - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: nil, - }} - oneFinishedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: makeSucceeded(trs[0]), - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: nil, - }} - oneFailedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: makeFailed(trs[0]), - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: nil, - }} - firstFinishedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: makeSucceeded(trs[0]), - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: nil, - }} - allFinishedState := []*PipelineRunTaskRun{{ - Task: task, - PipelineTask: &pts[0], - TaskRunName: "pipelinerun-mytask1", - TaskRun: makeSucceeded(trs[0]), - }, { - Task: task, - PipelineTask: &pts[1], - TaskRunName: "pipelinerun-mytask2", - TaskRun: makeSucceeded(trs[0]), - }} tcs := []struct { name string state []*PipelineRunTaskRun @@ -211,7 +214,7 @@ func TestGetNextTask_NoneStarted(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - nextTask := GetNextTask(tc.state) + nextTask := GetNextTask("somepipelinerun", tc.state, zap.NewNop().Sugar()) if d := cmp.Diff(nextTask, tc.expectedTask); d != "" { t.Fatalf("Expected to indicate first task should be run, but different state returned: %s", d) } @@ -262,3 +265,50 @@ func TestGetPipelineState_TaskDoesntExist(t *testing.T) { t.Fatalf("Expected error getting non-existent Tasks for Pipeline %s but got none", p.Name) } } + +func TestGetPipelineConditionStatus(t *testing.T) { + tcs := []struct { + name string + state []*PipelineRunTaskRun + expectedStatus corev1.ConditionStatus + }{ + { + name: "no-tasks-started", + state: noneStartedState, + expectedStatus: corev1.ConditionUnknown, + }, + { + name: "one-task-started", + state: oneStartedState, + expectedStatus: corev1.ConditionUnknown, + }, + { + name: "one-task-finished", + state: oneFinishedState, + expectedStatus: corev1.ConditionUnknown, + }, + { + name: "one-task-failed", + state: oneFailedState, + expectedStatus: corev1.ConditionFalse, + }, + { + name: "first-task-finished", + state: firstFinishedState, + expectedStatus: corev1.ConditionUnknown, + }, + { + name: "all-finished", + state: allFinishedState, + expectedStatus: corev1.ConditionTrue, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + c := GetPipelineConditionStatus("somepipelinerun", tc.state, zap.NewNop().Sugar()) + if c.Status != tc.expectedStatus { + t.Fatalf("Expected to get status %s but got %s for state %v", tc.expectedStatus, c.Status, tc.state) + } + }) + } +} diff --git a/test/pipelinerun_test.go b/test/pipelinerun_test.go index f337deb3ead..6775b000009 100644 --- a/test/pipelinerun_test.go +++ b/test/pipelinerun_test.go @@ -21,8 +21,11 @@ package test import ( "testing" + duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1" knativetest "github.com/knative/pkg/test" "github.com/knative/pkg/test/logging" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/knative/build-pipeline/pkg/apis/pipeline/v1alpha1" ) @@ -48,20 +51,30 @@ func TestPipelineRun(t *testing.T) { t.Fatalf("Failed to create PipelineRun `%s`: %s", hwPipelineRunName, err) } - // TODO wait for the Run to be successful - logger.Infof("Waiting for PipelineRun %s in namespace %s to be updated by controller", hwPipelineRunName, namespace) + logger.Infof("Waiting for PipelineRun %s in namespace %s to complete", hwPipelineRunName, namespace) if err := WaitForPipelineRunState(c, hwPipelineRunName, func(tr *v1alpha1.PipelineRun) (bool, error) { - if len(tr.Status.Conditions) > 0 { - // TODO: use actual conditions + c := tr.Status.GetCondition(duckv1alpha1.ConditionSucceeded) + if c != nil && c.Status == corev1.ConditionTrue { return true, nil } return false, nil - }, "TaskRunCompleted"); err != nil { - t.Errorf("Error waiting for TaskRun %s to finish: %s", hwTaskRunName, err) + }, "PipelineRunSuccess"); err != nil { + t.Errorf("Error waiting for PipelineRun %s to finish: %s", hwTaskRunName, err) } - - // TODO check that TaskRuns created - - // Verify that the init containers Build ran had 'taskOutput' written - // VerifyBuildOutput(t, c, namespace, taskOutput) + logger.Infof("Making sure the expected TaskRuns were created") + expectedTaskRuns := []string{ + hwPipelineName + hwPipelineTaskName1, + hwPipelineName + hwPipelineTaskName2, + } + for _, runName := range expectedTaskRuns { + r, err := c.TaskRunClient.Get(runName, metav1.GetOptions{}) + if err != nil { + t.Errorf("Couldn't get expected TaskRun %s: %s", runName, err) + } + c := r.Status.GetCondition(duckv1alpha1.ConditionSucceeded) + if c.Status != corev1.ConditionTrue { + t.Errorf("Expected TaskRun %s to have succeeded but Status is %s", runName, c.Status) + } + } + VerifyBuildOutput(t, c, namespace, taskOutput) }