client-go icon indicating copy to clipboard operation
client-go copied to clipboard

Bug in fake batch client?

Open CAJan93 opened this issue 9 months ago • 0 comments

Below I have a really simple test and a minimal working example.

In the test I am inserting 4 jobs into my fake client. I then delete all jobs that match both the labels AND the namespace. I marked the jobs that should be deleted with // match. The other 2 jobs should stay.

When I run this I get

Error:      	"map[App1:%!s(bool=true) App2:%!s(bool=true) OtherApp:%!s(bool=true)]" should have 2 item(s), but has 3

Why do App1, App2 and OtherApp not get deleted? Is this a bug in the fake k8s client?

package somepackage

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"
	batchv1 "k8s.io/api/batch/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"

	fake2 "k8s.io/client-go/kubernetes/fake"
)

func TestFunc(t *testing.T) {
	myNamespace := "namespace"
	myLabels := map[string]string{"key": "value"}

	allJobs := []runtime.Object{
		&batchv1.Job{ // match
			ObjectMeta: metav1.ObjectMeta{
				Name:      "App1",
				Namespace: myNamespace,
				Labels:    myLabels,
			},
		}, &batchv1.Job{ // match
			ObjectMeta: metav1.ObjectMeta{
				Name:      "App2",
				Namespace: myNamespace,
				Labels:    myLabels,
			},
		}, &batchv1.Job{ // other namespace
			ObjectMeta: metav1.ObjectMeta{
				Name:      "App3",
				Namespace: "otherNamespace",
				Labels:    myLabels,
			},
		}, &batchv1.Job{ // other labels
			ObjectMeta: metav1.ObjectMeta{
				Name:      "OtherApp",
				Namespace: myNamespace,
				Labels:    map[string]string{"other": "label"},
			},
		},
	}

	cliSet := fake2.NewSimpleClientset(allJobs...)

	err := cliSet.BatchV1().Jobs(myNamespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
		LabelSelector: labels.FormatLabels(myLabels),
	})

	jobs, err := cliSet.BatchV1().Jobs(myNamespace).List(context.Background(), metav1.ListOptions{}) 

	require.NoError(t, err)

	jobNameSet := map[string]bool{}
	for _, job := range jobs.Items {
		jobNameSet[job.Name] = true
	}
	require.Len(t, jobNameSet, 2, "Expected 2 jobs after deletion")
	require.NotContains(t, jobNameSet, "App1")
	require.NotContains(t, jobNameSet, "App2")
	require.Contains(t, jobNameSet, "App3", "Should exist, because other namespace")
	require.Contains(t, jobNameSet, "OtherApp", "Should exist, because other labels")

}

Also posted this to StackOverflow

CAJan93 avatar May 06 '24 16:05 CAJan93