Repository: argoproj/argo (go)

Issue:
When trying to delete a pod, and we do not find it, this should not be an error
```
time="2020-04-02T18:30:47Z" level=error msg="Failed to delete pod dev-devx-mpa-cost-res-analysis-argo-usw2-ppd-qal/mpa-cost-argo-kjt7l-2211751261 for gc: pods \"mpa-cost-argo-kjt7l-2211751261\" not found"
```

Pull request:
fix: Fix bug in deleting pods. Fixes #2571
Checklist:

* [x] Either (a) I've created an [enhancement proposal](https://github.com/argoproj/argo/issues/new/choose) and discussed it with the community, (b) this is a bug fix, or (c) this is a chore.
* [x] The title of the PR is (a) [conventional](https://www.conventionalcommits.org/en/v1.0.0/), (b) states what changed, and (c) suffixes the related issues number. E.g. `"fix(controller): Updates such and such. Fixes #1234"`.  
* [x] I have written unit and/or e2e tests for my change. PRs without these are unlike to be merged.
* [x] Optional. I've added My organization is added to the USERS.md.
* [ ] I've signed the CLA and required builds are green. 


Patch:
diff --git a/ui/src/app/workflows/components/workflow-list-item/workflow-list-item.tsx b/ui/src/app/workflows/components/workflow-list-item/workflow-list-item.tsx
index 6b780c491..192e0b762 100644
--- a/ui/src/app/workflows/components/workflow-list-item/workflow-list-item.tsx
+++ b/ui/src/app/workflows/components/workflow-list-item/workflow-list-item.tsx
@@ -17,7 +17,7 @@ export interface WorkflowListItemProps {
 }
 
 function wfDuration(workflow: models.WorkflowStatus, now: moment.Moment) {
-    const endTime = workflow.finishedAt ? moment(workflow.finishedAt) : now
+    const endTime = workflow.finishedAt ? moment(workflow.finishedAt) : now;
     return endTime.diff(moment(workflow.startedAt)) / 1000;
 }
 
@@ -66,9 +66,7 @@ export const WorkflowListItem = (props: WorkflowListItemProps) => (
                         <div className='workflow-list-item__content-details-row row'>
                             <div className='columns large-4'>DURATION:</div>
                             <div className='columns large-8'>
-                                <Ticker>
-                                    {now => <Duration durationMs={wfDuration(props.workflow.status, now)} />}
-                                </Ticker>
+                                <Ticker>{now => <Duration durationMs={wfDuration(props.workflow.status, now)} />}</Ticker>
                             </div>
                         </div>
                     </div>
diff --git a/workflow/common/util.go b/workflow/common/util.go
index e2fea48ab..6827b42ed 100644
--- a/workflow/common/util.go
+++ b/workflow/common/util.go
@@ -458,7 +458,7 @@ func DeletePod(c kubernetes.Interface, podName, namespace string) error {
 	for attempt := 0; attempt < deleteRetries; attempt++ {
 		err = c.CoreV1().Pods(namespace).Delete(podName, &metav1.DeleteOptions{})
 		if err == nil || apierr.IsNotFound(err) {
-			break
+			return nil
 		}
 		time.Sleep(100 * time.Millisecond)
 	}
diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go
index 7906967f5..facce409c 100644
--- a/workflow/controller/operator.go
+++ b/workflow/controller/operator.go
@@ -338,7 +338,7 @@ func (woc *wfOperationCtx) operate() {
 		onExitNode, err = woc.executeTemplate(onExitNodeName, &wfv1.WorkflowStep{Template: woc.wf.Spec.OnExit}, tmplCtx, woc.wf.Spec.Arguments, &executeTemplateOpts{onExitTemplate: true})
 		if err != nil {
 			// the error are handled in the callee so just log it.
-			woc.log.Errorf("%s error in exit template execution: %+v", woc.wf.Name, err)
+			woc.log.Errorf("error in exit template execution: %+v", err)
 			return
 		}
 		if onExitNode == nil || !onExitNode.Completed() {


Test patch:
diff --git a/workflow/common/util_test.go b/workflow/common/util_test.go
index 708393b3f..f5b46fb36 100644
--- a/workflow/common/util_test.go
+++ b/workflow/common/util_test.go
@@ -5,6 +5,8 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/kubernetes/fake"
 
 	wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
 )
@@ -68,3 +70,17 @@ spec:
 	_, err = SplitWorkflowYAMLFile([]byte(invalidWf), false)
 	assert.EqualError(t, err, `error unmarshaling JSON: while decoding JSON: json: unknown field "doesNotExist"`)
 }
+
+func TestDeletePod(t *testing.T) {
+	kube := fake.NewSimpleClientset(&corev1.Pod{
+		ObjectMeta: v1.ObjectMeta{Name: "my-pod", Namespace: "my-ns"},
+	})
+	t.Run("Exists", func(t *testing.T) {
+		err := DeletePod(kube, "my-pod", "my-ms")
+		assert.NoError(t, err)
+	})
+	t.Run("NotExists", func(t *testing.T) {
+		err := DeletePod(kube, "not-exists", "my-ms")
+		assert.NoError(t, err)
+	})
+}