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:
6
Makefile
6
Makefile
@@ -83,11 +83,9 @@ else
|
||||
endif
|
||||
|
||||
test:
|
||||
@echo "Testing..."
|
||||
$Q go test -mod=vendor $(if $V,-v) $(allpackages) # install -race libs to speed up next run
|
||||
ifndef CI
|
||||
@echo "Testing Outside CI..."
|
||||
$Q GODEBUG=cgocheck=2 go test -mod=vendor $(allpackages)
|
||||
@echo "Testing..."
|
||||
$Q go test -mod=vendor $(if $V,-v) $(allpackages)
|
||||
else
|
||||
@echo "Testing in CI..."
|
||||
$Q mkdir -p test
|
||||
|
||||
12
node/pod.go
12
node/pod.go
@@ -145,20 +145,18 @@ func (pc *PodController) deletePod(ctx context.Context, namespace, name string)
|
||||
ctx = addPodAttributes(ctx, span, pod)
|
||||
|
||||
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)
|
||||
return delErr
|
||||
}
|
||||
|
||||
log.G(ctx).Debug("Deleted pod from provider")
|
||||
|
||||
if !errors.IsNotFound(delErr) {
|
||||
if err := pc.forceDeletePodResource(ctx, namespace, name); err != nil {
|
||||
span.SetStatus(err)
|
||||
return err
|
||||
}
|
||||
log.G(ctx).Info("Deleted pod from Kubernetes")
|
||||
if err := pc.forceDeletePodResource(ctx, namespace, name); err != nil {
|
||||
span.SetStatus(err)
|
||||
return err
|
||||
}
|
||||
log.G(ctx).Info("Deleted pod from Kubernetes")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -19,11 +19,14 @@ import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
pkgerrors "github.com/pkg/errors"
|
||||
"github.com/virtual-kubelet/virtual-kubelet/errdefs"
|
||||
testutil "github.com/virtual-kubelet/virtual-kubelet/internal/test/util"
|
||||
"gotest.tools/assert"
|
||||
is "gotest.tools/assert/cmp"
|
||||
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"
|
||||
)
|
||||
|
||||
@@ -33,6 +36,8 @@ type mockProvider struct {
|
||||
creates int
|
||||
updates int
|
||||
deletes int
|
||||
|
||||
errorOnDelete 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 {
|
||||
if m.errorOnDelete != nil {
|
||||
return m.errorOnDelete
|
||||
}
|
||||
delete(m.pods, path.Join(p.GetNamespace(), p.GetName()))
|
||||
m.deletes++
|
||||
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.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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user