Fix error handling for delete pod (#685)

* Fix error handling for delete pod

- Error handling was looking for a k8s error from the provider, but
  providers should be using errdefs.
- Error handling was returning early if pod was not found and deleting
  from k8s in all other cases.

* Don't run unit tests twice
This commit is contained in:
Brian Goff
2019-06-29 00:07:24 -07:00
committed by Pires
parent 07379f7b1f
commit b915cde1ae
3 changed files with 75 additions and 11 deletions

View File

@@ -83,11 +83,9 @@ else
endif endif
test: test:
@echo "Testing..."
$Q go test -mod=vendor $(if $V,-v) $(allpackages) # install -race libs to speed up next run
ifndef CI ifndef CI
@echo "Testing Outside CI..." @echo "Testing..."
$Q GODEBUG=cgocheck=2 go test -mod=vendor $(allpackages) $Q go test -mod=vendor $(if $V,-v) $(allpackages)
else else
@echo "Testing in CI..." @echo "Testing in CI..."
$Q mkdir -p test $Q mkdir -p test

View File

@@ -145,20 +145,18 @@ func (pc *PodController) deletePod(ctx context.Context, namespace, name string)
ctx = addPodAttributes(ctx, span, pod) ctx = addPodAttributes(ctx, span, pod)
var delErr error var delErr error
if delErr = pc.provider.DeletePod(ctx, pod); delErr != nil && errors.IsNotFound(delErr) { if delErr = pc.provider.DeletePod(ctx, pod); delErr != nil && !errdefs.IsNotFound(delErr) {
span.SetStatus(delErr) span.SetStatus(delErr)
return delErr return delErr
} }
log.G(ctx).Debug("Deleted pod from provider") log.G(ctx).Debug("Deleted pod from provider")
if !errors.IsNotFound(delErr) { if err := pc.forceDeletePodResource(ctx, namespace, name); err != nil {
if err := pc.forceDeletePodResource(ctx, namespace, name); err != nil { span.SetStatus(err)
span.SetStatus(err) return err
return err
}
log.G(ctx).Info("Deleted pod from Kubernetes")
} }
log.G(ctx).Info("Deleted pod from Kubernetes")
return nil return nil
} }

View File

@@ -19,11 +19,14 @@ import (
"path" "path"
"testing" "testing"
pkgerrors "github.com/pkg/errors"
"github.com/virtual-kubelet/virtual-kubelet/errdefs" "github.com/virtual-kubelet/virtual-kubelet/errdefs"
testutil "github.com/virtual-kubelet/virtual-kubelet/internal/test/util" testutil "github.com/virtual-kubelet/virtual-kubelet/internal/test/util"
"gotest.tools/assert" "gotest.tools/assert"
is "gotest.tools/assert/cmp" is "gotest.tools/assert/cmp"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
) )
@@ -33,6 +36,8 @@ type mockProvider struct {
creates int creates int
updates int updates int
deletes int deletes int
errorOnDelete error
} }
func (m *mockProvider) CreatePod(ctx context.Context, pod *corev1.Pod) error { func (m *mockProvider) CreatePod(ctx context.Context, pod *corev1.Pod) error {
@@ -64,6 +69,9 @@ func (m *mockProvider) GetPodStatus(ctx context.Context, namespace, name string)
} }
func (m *mockProvider) DeletePod(ctx context.Context, p *corev1.Pod) error { func (m *mockProvider) DeletePod(ctx context.Context, p *corev1.Pod) error {
if m.errorOnDelete != nil {
return m.errorOnDelete
}
delete(m.pods, path.Join(p.GetNamespace(), p.GetName())) delete(m.pods, path.Join(p.GetNamespace(), p.GetName()))
m.deletes++ m.deletes++
return nil return nil
@@ -293,3 +301,63 @@ func TestPodNoSpecChange(t *testing.T) {
assert.Check(t, is.Equal(svr.mock.creates, 1)) assert.Check(t, is.Equal(svr.mock.creates, 1))
assert.Check(t, is.Equal(svr.mock.updates, 0)) assert.Check(t, is.Equal(svr.mock.updates, 0))
} }
func TestPodDelete(t *testing.T) {
type testCase struct {
desc string
delErr error
}
cases := []testCase{
{desc: "no error on delete", delErr: nil},
{desc: "not found error on delete", delErr: errdefs.NotFound("not found")},
{desc: "unknown error on delete", delErr: pkgerrors.New("random error")},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
c := newTestController()
c.mock.errorOnDelete = tc.delErr
pod := &corev1.Pod{}
pod.ObjectMeta.Namespace = "default"
pod.ObjectMeta.Name = "nginx"
pod.Spec = corev1.PodSpec{
Containers: []corev1.Container{
corev1.Container{
Name: "nginx",
Image: "nginx:1.15.12",
},
},
}
pc := c.client.CoreV1().Pods("default")
p, err := pc.Create(pod)
assert.NilError(t, err)
ctx := context.Background()
err = c.createOrUpdatePod(ctx, p) // make sure it's actually created
assert.NilError(t, err)
assert.Check(t, is.Equal(c.mock.creates, 1))
err = c.deletePod(ctx, pod.Namespace, pod.Name)
assert.Equal(t, pkgerrors.Cause(err), err)
var expectDeletes int
if tc.delErr == nil {
expectDeletes = 1
}
assert.Check(t, is.Equal(c.mock.deletes, expectDeletes))
expectDeleted := tc.delErr == nil || errdefs.IsNotFound(tc.delErr)
_, err = pc.Get(pod.Name, metav1.GetOptions{})
if expectDeleted {
assert.Assert(t, errors.IsNotFound(err))
} else {
assert.NilError(t, err)
}
})
}
}