Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit test for Uprobe in container #349

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/bpfman-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,19 @@
os.Exit(1)
}

containerGetter, err := bpfmanagent.NewRealContainerGetter(nodeName)
if err != nil {
setupLog.Error(err, "unable to create containerGetter")
os.Exit(1)
}

Check warning on line 146 in cmd/bpfman-agent/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/bpfman-agent/main.go#L142-L146

Added lines #L142 - L146 were not covered by tests

common := bpfmanagent.ReconcilerCommon{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
GrpcConn: conn,
BpfmanClient: gobpfman.NewBpfmanClient(conn),
NodeName: nodeName,
Containers: containerGetter,

Check warning on line 154 in cmd/bpfman-agent/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/bpfman-agent/main.go#L154

Added line #L154 was not covered by tests
}

if err = (&bpfmanagent.XdpProgramReconciler{
Expand Down
1 change: 1 addition & 0 deletions controllers/bpfman-agent/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type ReconcilerCommon struct {
finalizer string
recType string
appOwner metav1.Object // Set if the owner is an application
Containers ContainerGetter
}

// bpfmanReconciler defines a generic bpfProgram K8s object reconciler which can
Expand Down
61 changes: 40 additions & 21 deletions controllers/bpfman-agent/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,46 @@
"github.com/go-logr/logr"
)

// Figure out the list of container pids in which the program should be
// attached.
func getContainers(
ctx context.Context,
containerSelector *bpfmaniov1alpha1.ContainerSelector,
nodeName string,
logger logr.Logger) (*[]containerInfo, error) {
type ContainerInfo struct {
podName string
containerName string
pid int64
}

// Create an interface for getting the list of containers in which the program
// should be attached so we can mock it in unit tests.
type ContainerGetter interface {
// Get the list of containers on this node that match the containerSelector.
GetContainers(ctx context.Context, containerSelector *bpfmaniov1alpha1.ContainerSelector,
logger logr.Logger) (*[]ContainerInfo, error)
}

type RealContainerGetter struct {
nodeName string
clientSet kubernetes.Interface
}

func NewRealContainerGetter(nodeName string) (*RealContainerGetter, error) {

Check warning on line 54 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L54

Added line #L54 was not covered by tests
clientSet, err := getClientset()
if err != nil {
return nil, fmt.Errorf("failed to get clientset: %v", err)
}

containerGetter := RealContainerGetter{
nodeName: nodeName,
clientSet: clientSet,
}

return &containerGetter, nil

Check warning on line 65 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L60-L65

Added lines #L60 - L65 were not covered by tests
}

func (c *RealContainerGetter) GetContainers(
ctx context.Context,
containerSelector *bpfmaniov1alpha1.ContainerSelector,
logger logr.Logger) (*[]ContainerInfo, error) {

Check warning on line 72 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L71-L72

Added lines #L71 - L72 were not covered by tests
// Get the list of pods that match the selector.
podList, err := getPodsForNode(ctx, clientSet, containerSelector, nodeName)
podList, err := c.getPodsForNode(ctx, containerSelector)

Check warning on line 74 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L74

Added line #L74 was not covered by tests
if err != nil {
return nil, fmt.Errorf("failed to get pod list: %v", err)
}
Expand All @@ -64,8 +89,8 @@

// getPodsForNode returns a list of pods on the given node that match the given
// container selector.
func getPodsForNode(ctx context.Context, clientset kubernetes.Interface,
containerSelector *bpfmaniov1alpha1.ContainerSelector, nodeName string) (*v1.PodList, error) {
func (c *RealContainerGetter) getPodsForNode(ctx context.Context,
containerSelector *bpfmaniov1alpha1.ContainerSelector) (*v1.PodList, error) {

Check warning on line 93 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L93

Added line #L93 was not covered by tests

selectorString := metav1.FormatLabelSelector(&containerSelector.Pods)

Expand All @@ -74,33 +99,27 @@
}

listOptions := metav1.ListOptions{
FieldSelector: "spec.nodeName=" + nodeName,
FieldSelector: "spec.nodeName=" + c.nodeName,

Check warning on line 102 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L102

Added line #L102 was not covered by tests
}

if selectorString != "<none>" {
listOptions.LabelSelector = selectorString
}

podList, err := clientset.CoreV1().Pods(containerSelector.Namespace).List(ctx, listOptions)
podList, err := c.clientSet.CoreV1().Pods(containerSelector.Namespace).List(ctx, listOptions)

Check warning on line 109 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L109

Added line #L109 was not covered by tests
if err != nil {
return nil, fmt.Errorf("error getting pod list: %v", err)
}

return podList, nil
}

type containerInfo struct {
podName string
containerName string
pid int64
}

// getContainerInfo returns a list of containerInfo for the given pod list and container names.
func getContainerInfo(podList *v1.PodList, containerNames *[]string, logger logr.Logger) (*[]containerInfo, error) {
func getContainerInfo(podList *v1.PodList, containerNames *[]string, logger logr.Logger) (*[]ContainerInfo, error) {

Check warning on line 118 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L118

Added line #L118 was not covered by tests

crictl := "/usr/local/bin/crictl"

containers := []containerInfo{}
containers := []ContainerInfo{}

Check warning on line 122 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L122

Added line #L122 was not covered by tests

for i, pod := range podList.Items {
logger.V(1).Info("Pod", "index", i, "Name", pod.Name, "Namespace", pod.Namespace, "NodeName", pod.Spec.NodeName)
Expand Down Expand Up @@ -196,7 +215,7 @@
continue
}

container := containerInfo{
container := ContainerInfo{

Check warning on line 218 in controllers/bpfman-agent/containers.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/containers.go#L218

Added line #L218 was not covered by tests
podName: pod.Name,
containerName: containerName,
pid: containerPid,
Expand Down
2 changes: 1 addition & 1 deletion controllers/bpfman-agent/tc-program.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@

// There is a container selector, so see if there are any matching
// containers on this node.
containerInfo, err := getContainers(ctx, r.currentTcProgram.Spec.Containers, r.NodeName, r.Logger)
containerInfo, err := r.Containers.GetContainers(ctx, r.currentTcProgram.Spec.Containers, r.Logger)

Check warning on line 186 in controllers/bpfman-agent/tc-program.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/tc-program.go#L186

Added line #L186 was not covered by tests
if err != nil {
return nil, fmt.Errorf("failed to get container pids: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion controllers/bpfman-agent/tcx-program.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@

// There is a container selector, so see if there are any matching
// containers on this node.
containerInfo, err := getContainers(ctx, r.currentTcxProgram.Spec.Containers, r.NodeName, r.Logger)
containerInfo, err := r.Containers.GetContainers(ctx, r.currentTcxProgram.Spec.Containers, r.Logger)

Check warning on line 152 in controllers/bpfman-agent/tcx-program.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/tcx-program.go#L152

Added line #L152 was not covered by tests
if err != nil {
return nil, fmt.Errorf("failed to get container pids: %v", err)
}
Expand Down
84 changes: 84 additions & 0 deletions controllers/bpfman-agent/test_common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package bpfmanagent

import (
"context"
"testing"

bpfmaniov1alpha1 "github.com/bpfman/bpfman-operator/apis/v1alpha1"
"github.com/go-logr/logr"

"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientGoFake "k8s.io/client-go/kubernetes/fake"
)

type FakeContainerGetter struct {
containerList *[]ContainerInfo
}

func (f *FakeContainerGetter) GetContainers(ctx context.Context, containerSelector *bpfmaniov1alpha1.ContainerSelector,
logger logr.Logger) (*[]ContainerInfo, error) {
return f.containerList, nil
}

func TestGetPods(t *testing.T) {
ctx := context.TODO()

// Create a fake clientset
clientset := clientGoFake.NewSimpleClientset()

// Create a ContainerSelector
containerSelector := &bpfmaniov1alpha1.ContainerSelector{
Pods: metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "test",
},
},
Namespace: "default",
}

nodeName := "test-node"

// Create a Pod that matches the label selector and is on the correct node
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "default",
Labels: map[string]string{
"app": "test",
},
},
Spec: v1.PodSpec{
NodeName: nodeName,
},
}

containerGetter := RealContainerGetter{
nodeName: nodeName,
clientSet: clientset,
}

// Add the Pod to the fake clientset
_, err := clientset.CoreV1().Pods("default").Create(ctx, pod, metav1.CreateOptions{})
require.NoError(t, err)

// Call getPods and check the returned PodList
podList, err := containerGetter.getPodsForNode(ctx, containerSelector)
require.NoError(t, err)
require.Len(t, podList.Items, 1)
require.Equal(t, "test-pod", podList.Items[0].Name)

// Try another selector
// Create a ContainerSelector
containerSelector = &bpfmaniov1alpha1.ContainerSelector{
Pods: metav1.LabelSelector{
MatchLabels: map[string]string{},
},
}

podList, err = containerGetter.getPodsForNode(ctx, containerSelector)
require.NoError(t, err)
require.Len(t, podList.Items, 1)
require.Equal(t, "test-pod", podList.Items[0].Name)

Check warning on line 83 in controllers/bpfman-agent/test_common.go

View check run for this annotation

Codecov / codecov/patch

controllers/bpfman-agent/test_common.go#L25-L83

Added lines #L25 - L83 were not covered by tests
}
2 changes: 1 addition & 1 deletion controllers/bpfman-agent/uprobe-program.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (r *UprobeProgramReconciler) getExpectedBpfPrograms(ctx context.Context) (*

// There is a container selector, so see if there are any matching
// containers on this node.
containerInfo, err := getContainers(ctx, r.currentUprobeProgram.Spec.Containers, r.NodeName, r.Logger)
containerInfo, err := r.Containers.GetContainers(ctx, r.currentUprobeProgram.Spec.Containers, r.Logger)
if err != nil {
return nil, fmt.Errorf("failed to get container pids: %v", err)
}
Expand Down
Loading
Loading