diff --git a/cmd/kueuectl/app/list/list_test.go b/cmd/kueuectl/app/list/list_test.go index d3be6a017a..b4b6dcdefd 100644 --- a/cmd/kueuectl/app/list/list_test.go +++ b/cmd/kueuectl/app/list/list_test.go @@ -125,9 +125,9 @@ cq2 cohort2 0 0 false 120m Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAMESPACE NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -ns1 wl1 j1 lq1 cq1 PENDING 60m -ns2 wl2 j2 lq2 cq2 PENDING 120m + wantOut: `NAMESPACE NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +ns1 wl1 j1 lq1 cq1 PENDING 60m +ns2 wl2 j2 lq2 cq2 PENDING 120m `, }, "should print workload list with all namespaces (short command and flag)": { @@ -148,9 +148,9 @@ ns2 wl2 j2 lq2 cq2 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAMESPACE NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -ns1 wl1 j1 lq1 cq1 PENDING 60m -ns2 wl2 j2 lq2 cq2 PENDING 120m + wantOut: `NAMESPACE NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +ns1 wl1 j1 lq1 cq1 PENDING 60m +ns2 wl2 j2 lq2 cq2 PENDING 120m `, }, } diff --git a/cmd/kueuectl/app/list/list_workload_printer.go b/cmd/kueuectl/app/list/list_workload_printer.go index fa3956790c..f550b82f31 100644 --- a/cmd/kueuectl/app/list/list_workload_printer.go +++ b/cmd/kueuectl/app/list/list_workload_printer.go @@ -22,6 +22,7 @@ import ( "io" "strings" + apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/duration" @@ -75,6 +76,7 @@ func (p *listWorkloadPrinter) PrintObj(obj runtime.Object, out io.Writer) error {Name: "ClusterQueue", Type: "string"}, {Name: "Status", Type: "string"}, {Name: "Position in Queue", Type: "string"}, + {Name: "Exec Time", Type: "string"}, {Name: "Age", Type: "string"}, }, Rows: p.printWorkloadList(list), @@ -138,6 +140,19 @@ func (p *listWorkloadPrinter) printWorkload(wl *v1beta1.Workload) metav1.TableRo positionInQueue = fmt.Sprintf("%d", pendingWorkload.PositionInLocalQueue) } + var execTime string + if admittedCond := apimeta.FindStatusCondition(wl.Status.Conditions, v1beta1.WorkloadAdmitted); admittedCond != nil && + admittedCond.Status == metav1.ConditionTrue { + finishedTime := p.clock.Now() + + if finishedCond := apimeta.FindStatusCondition(wl.Status.Conditions, v1beta1.WorkloadFinished); finishedCond != nil && + finishedCond.Status == metav1.ConditionTrue { + finishedTime = finishedCond.LastTransitionTime.Time + } + + execTime = duration.HumanDuration(finishedTime.Sub(admittedCond.LastTransitionTime.Time)) + } + row.Cells = []any{ wl.Name, strings.Join(p.crdTypes(wl), ", "), @@ -146,6 +161,7 @@ func (p *listWorkloadPrinter) printWorkload(wl *v1beta1.Workload) metav1.TableRo clusterQueueName, strings.ToUpper(workload.Status(wl)), positionInQueue, + execTime, duration.HumanDuration(p.clock.Since(wl.CreationTimestamp.Time)), } diff --git a/cmd/kueuectl/app/list/list_workload_test.go b/cmd/kueuectl/app/list/list_workload_test.go index eb70833f9c..07922f747e 100644 --- a/cmd/kueuectl/app/list/list_workload_test.go +++ b/cmd/kueuectl/app/list/list_workload_test.go @@ -84,8 +84,8 @@ func TestWorkloadCmd(t *testing.T) { Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with localqueue filter": { @@ -106,8 +106,8 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with localqueue filter (short flag)": { @@ -128,8 +128,8 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with clusterqueue filter": { @@ -150,8 +150,8 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with clusterqueue filter (short flag)": { @@ -172,8 +172,8 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with all status flag": { @@ -194,29 +194,71 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadAdmitted, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), utiltesting.MakeWorkload("wl3", metav1.NamespaceDefault). - OwnerReference(batchv1.SchemeGroupVersion.WithKind("Job"), "j3", "test-uid"). + OwnerReference(rayv1.GroupVersion.WithKind("RayJob"), "j3", "test-uid"). Queue("lq3"). Active(true). Admission(utiltesting.MakeAdmission("cq3").Obj()). + Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). + Conditions([]metav1.Condition{ + { + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), + }, + }...). + Obj(), + utiltesting.MakeWorkload("wl4", metav1.NamespaceDefault). + OwnerReference(batchv1.SchemeGroupVersion.WithKind("Job"), "j4", "test-uid"). + Queue("lq4"). + Active(true). + Admission(utiltesting.MakeAdmission("cq4").Obj()). Creation(testStartTime.Add(-3 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadFinished, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)), + }, + { + Type: kueue.WorkloadFinished, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), + }, + }...). + Obj(), + utiltesting.MakeWorkload("wl5", metav1.NamespaceDefault). + OwnerReference(batchv1.SchemeGroupVersion.WithKind("Job"), "j5", "test-uid"). + Queue("lq5"). + Active(true). + Admission(utiltesting.MakeAdmission("cq5").Obj()). + Creation(testStartTime.Add(-3 * time.Hour).Truncate(time.Second)). + Conditions([]metav1.Condition{ + { + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)), + }, + { + Type: kueue.WorkloadFinished, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m -wl2 j2 lq2 cq2 ADMITTED 120m -wl3 j3 lq3 cq3 FINISHED 3h + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m +wl2 j2 lq2 cq2 ADMITTED 60m 120m +wl3 j3 lq3 cq3 PENDING 120m +wl4 j4 lq4 cq4 FINISHED 60m 3h +wl5 j5 lq5 cq5 ADMITTED 120m 3h `, }, "should print workload list with only admitted and finished status flags": { @@ -237,8 +279,9 @@ wl3 j3 lq3 cq3 FINISHED Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadAdmitted, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), @@ -250,15 +293,21 @@ wl3 j3 lq3 cq3 FINISHED Creation(testStartTime.Add(-3 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadFinished, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)), + }, + { + Type: kueue.WorkloadFinished, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl2 j2 lq2 cq2 ADMITTED 120m -wl3 j3 lq3 cq3 FINISHED 3h + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl2 j2 lq2 cq2 ADMITTED 60m 120m +wl3 j3 lq3 cq3 FINISHED 60m 3h `, }, "should print workload list with only pending filter": { @@ -285,8 +334,8 @@ wl3 j3 lq3 cq3 FINISHED }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with only quotareserved filter": { @@ -319,8 +368,8 @@ wl1 j1 lq1 cq1 PENDING }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 QUOTARESERVED 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 QUOTARESERVED 60m `, }, "should print workload list with only admitted filter": { @@ -334,8 +383,9 @@ wl1 j1 lq1 cq1 QUOTARESERVED Creation(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadAdmitted, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), @@ -347,14 +397,15 @@ wl1 j1 lq1 cq1 QUOTARESERVED Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadAdmitted, - Status: metav1.ConditionFalse, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), }, }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 ADMITTED 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 ADMITTED 60m 60m `, }, "should print workload list with only finished status filter": { @@ -368,8 +419,14 @@ wl1 j1 lq1 cq1 ADMITTED Creation(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadFinished, - Status: metav1.ConditionTrue, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), + }, + { + Type: kueue.WorkloadFinished, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Truncate(time.Second)), }, }...). Obj(), @@ -381,14 +438,20 @@ wl1 j1 lq1 cq1 ADMITTED Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Conditions([]metav1.Condition{ { - Type: kueue.WorkloadFinished, - Status: metav1.ConditionFalse, + Type: kueue.WorkloadAdmitted, + Status: metav1.ConditionTrue, + LastTransitionTime: metav1.NewTime(testStartTime.Add(-1 * time.Hour).Truncate(time.Second)), + }, + { + Type: kueue.WorkloadFinished, + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.NewTime(testStartTime.Truncate(time.Second)), }, }...). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 FINISHED 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 FINISHED 60m 60m `, }, "should print workload list with label selector filter": { @@ -411,8 +474,8 @@ wl1 j1 lq1 cq1 FINISHED Label("key", "value2"). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with label selector filter (short flag)": { @@ -435,8 +498,8 @@ wl1 j1 lq1 cq1 PENDING Label("key", "value2"). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 60m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 60m `, }, "should print workload list with Job types": { @@ -494,10 +557,10 @@ wl1 j1 lq1 cq1 PENDING Creation(testStartTime.Add(-3 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 job j1 lq1 cq1 PENDING 60m -wl2 rayjob.ray.io j2 lq2 cq2 PENDING 120m -wl3 pytorchjob.kubeflow.... j3 lq3 cq3 PENDING 3h + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 job j1 lq1 cq1 PENDING 60m +wl2 rayjob.ray.io j2 lq2 cq2 PENDING 120m +wl3 pytorchjob.kubeflow.... j3 lq3 cq3 PENDING 3h `, }, "should print workload list with resource filter": { @@ -553,8 +616,8 @@ wl3 pytorchjob.kubeflow.... j3 lq3 cq3 PENDING }, }, }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 job.batch job-test lq1 cq1 PENDING 120m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 job.batch job-test lq1 cq1 PENDING 120m `, }, "should print workload list with resource filter and composable jobs": { @@ -619,8 +682,8 @@ wl1 job.batch job-test lq1 cq1 PENDING }, }, }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl2 pod pod-test-1 lq2 cq2 PENDING 3h + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl2 pod pod-test-1 lq2 cq2 PENDING 3h `, }, "should print workload list with custom resource filter": { @@ -687,8 +750,8 @@ wl2 pod pod-test-1 lq2 cq2 PENDING }, }, }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 rayjob.ray.io job-test lq1 cq1 PENDING 120m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 rayjob.ray.io job-test lq1 cq1 PENDING 120m `, }, "should print workload list with full resource filter": { @@ -755,8 +818,8 @@ wl1 rayjob.ray.io job-test lq1 cq1 PENDING }, }, }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 rayjob.ray.io job-test lq1 cq1 PENDING 120m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 rayjob.ray.io job-test lq1 cq1 PENDING 120m `, }, "should print workload list with position in queue": { @@ -798,9 +861,9 @@ wl1 rayjob.ray.io job-test lq1 cq1 PENDING Creation(testStartTime.Add(-2 * time.Hour).Truncate(time.Second)). Obj(), }, - wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 j1 lq1 cq1 PENDING 12 60m -wl2 j2 lq2 cq2 PENDING 22 120m + wantOut: `NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 j1 lq1 cq1 PENDING 12 60m +wl2 j2 lq2 cq2 PENDING 22 120m `, }, "should print not found error": { diff --git a/test/integration/kueuectl/list_test.go b/test/integration/kueuectl/list_test.go index 0263050e0d..1b30471630 100644 --- a/test/integration/kueuectl/list_test.go +++ b/test/integration/kueuectl/list_test.go @@ -216,8 +216,8 @@ very-long-cluster-queue-name 0 0 gomega.Expect(err).NotTo(gomega.HaveOccurred(), "%s: %s", err, output) gomega.Expect(errOutput.String()).Should(gomega.BeEmpty()) - gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -wl1 lq1 PENDING %s + gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +wl1 lq1 PENDING %s `, duration.HumanDuration(executeTime.Sub(wl1.CreationTimestamp.Time))))) }) @@ -235,10 +235,10 @@ wl1 lq1 PENDING gomega.Expect(err).NotTo(gomega.HaveOccurred(), "%s: %s", err, output) gomega.Expect(errOutput.String()).Should(gomega.BeEmpty()) - gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE AGE -very-long-workload-name lq1 PENDING %s -wl1 lq1 PENDING %s -wl2 very-long-local-queue-name PENDING %s + gomega.Expect(output.String()).Should(gomega.Equal(fmt.Sprintf(`NAME JOB TYPE JOB NAME LOCALQUEUE CLUSTERQUEUE STATUS POSITION IN QUEUE EXEC TIME AGE +very-long-workload-name lq1 PENDING %s +wl1 lq1 PENDING %s +wl2 very-long-local-queue-name PENDING %s `, duration.HumanDuration(executeTime.Sub(wl3.CreationTimestamp.Time)), duration.HumanDuration(executeTime.Sub(wl1.CreationTimestamp.Time)),