Skip to content

Commit

Permalink
Add app integeration test
Browse files Browse the repository at this point in the history
Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com>
  • Loading branch information
msherif1234 committed Jun 24, 2024
1 parent 4c3fa0b commit 40f93c8
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 51 deletions.
83 changes: 83 additions & 0 deletions test/integration/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//go:build integration_tests
// +build integration_tests

package integration

import (
"bytes"
"context"
"io"
"testing"
"time"

"github.com/kong/kubernetes-testing-framework/pkg/clusters"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
appGoCounterKustomize = "https://github.com/bpfman/bpfman/examples/config/default/go-app-counter/?timeout=120&ref=main"
appGoCounterUserspaceNs = "go-application-counter"
appGoCounterUserspaceDsName = "go-application-counter-ds"
)

func TestApplicationGoCounter(t *testing.T) {
t.Log("deploying target required for uprobe counter program if its not already deployed")
require.NoError(t, clusters.KustomizeDeployForCluster(ctx, env.Cluster(), targetKustomize))

t.Log("waiting for go target userspace daemon to be available")
require.Eventually(t, func() bool {
daemon, err := env.Cluster().Client().AppsV1().DaemonSets(targetUserspaceNs).Get(ctx, targetUserspaceDsName, metav1.GetOptions{})
require.NoError(t, err)
return daemon.Status.DesiredNumberScheduled == daemon.Status.NumberAvailable
},
// Wait 5 minutes since cosign is slow, https://github.com/bpfman/bpfman/issues/1043
5*time.Minute, 10*time.Second)

t.Log("deploying application counter program")
require.NoError(t, clusters.KustomizeDeployForCluster(ctx, env.Cluster(), appGoCounterKustomize))
addCleanup(func(context.Context) error {
cleanupLog("cleaning up application counter program")
return clusters.KustomizeDeleteForCluster(ctx, env.Cluster(), appGoCounterKustomize)
})

t.Log("waiting for go application counter userspace daemon to be available")
require.Eventually(t, func() bool {
daemon, err := env.Cluster().Client().AppsV1().DaemonSets(appGoCounterUserspaceNs).Get(ctx, appGoCounterUserspaceDsName, metav1.GetOptions{})
require.NoError(t, err)
return daemon.Status.DesiredNumberScheduled == daemon.Status.NumberAvailable
},
// Wait 5 minutes since cosign is slow, https://github.com/bpfman/bpfman/issues/1043
5*time.Minute, 10*time.Second)

pods, err := env.Cluster().Client().CoreV1().Pods(appGoCounterUserspaceNs).List(ctx, metav1.ListOptions{LabelSelector: "name=go-application-counter"})
require.NoError(t, err)
goAppCounterPod := pods.Items[0]

checkFunctions := []func(t *testing.T, output *bytes.Buffer) bool{
doAppKprobeCheck,
doAppTcCheck,
doAppTracepointCheck,
doAppUprobeCheck,
doAppXdpCheck,
}

for idx, f := range checkFunctions {
req := env.Cluster().Client().CoreV1().Pods(appGoCounterUserspaceNs).GetLogs(goAppCounterPod.Name, &corev1.PodLogOptions{})
require.Eventually(t, func() bool {
logs, err := req.Stream(ctx)
require.NoError(t, err)
defer logs.Close()
output := new(bytes.Buffer)
_, err = io.Copy(output, logs)
require.NoError(t, err)

if f(t, output) {
return true
}
t.Logf("check %d failed retrying, output %s", idx, output.String())
return false
}, 30*time.Second, time.Second)
}
}
113 changes: 113 additions & 0 deletions test/integration/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//go:build integration_tests
// +build integration_tests

package integration

import (
"bytes"
"regexp"
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func doKprobeCheck(t *testing.T, output *bytes.Buffer) bool {
str := `Kprobe count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d kprobe executions so far, BPF program is functioning", count)
return true
}
return false
}

func doAppKprobeCheck(t *testing.T, output *bytes.Buffer) bool {
str := `Kprobe: count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d kprobe executions so far, BPF program is functioning", count)
return true
}
return false
}

func doTcCheck(t *testing.T, output *bytes.Buffer) bool {
if strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
t.Log("TC BPF program is functioning")
return true
}
return false
}

func doAppTcCheck(t *testing.T, output *bytes.Buffer) bool {
if strings.Contains(output.String(), "TC:") && strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
t.Log("TC BPF program is functioning")
return true
}
return false
}

func doTracepointCheck(t *testing.T, output *bytes.Buffer) bool {
str := `SIGUSR1 signal count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d SIGUSR1 signals so far, BPF program is functioning", count)
return true
}
return false
}

func doAppTracepointCheck(t *testing.T, output *bytes.Buffer) bool {
str := `Tracepoint: SIGUSR1 signal count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d SIGUSR1 signals so far, BPF program is functioning", count)
return true
}
return false
}

func doUprobeCheck(t *testing.T, output *bytes.Buffer) bool {
str := `Uprobe count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d uprobe executions so far, BPF program is functioning", count)
return true
}
return false
}

func doAppUprobeCheck(t *testing.T, output *bytes.Buffer) bool {
str := `Uprobe: count: ([0-9]+)`
if ok, count := doProbeCommonCheck(t, output, str); ok {
t.Logf("counted %d uprobe executions so far, BPF program is functioning", count)
return true
}
return false
}

func doXdpCheck(t *testing.T, output *bytes.Buffer) bool {
if strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
t.Log("XDP BPF program is functioning")
return true
}
return false
}

func doAppXdpCheck(t *testing.T, output *bytes.Buffer) bool {
if strings.Contains(output.String(), "XDP:") && strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
t.Log("XDP BPF program is functioning")
return true
}
return false
}

func doProbeCommonCheck(t *testing.T, output *bytes.Buffer, str string) (bool, int) {
want := regexp.MustCompile(str)
matches := want.FindAllStringSubmatch(output.String(), -1)
if len(matches) >= 1 && len(matches[0]) >= 2 {
count, err := strconv.Atoi(matches[0][1])
require.NoError(t, err)
if count > 0 {
return true, count
}
}
return false, 0
}
14 changes: 1 addition & 13 deletions test/integration/kprobe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"bytes"
"context"
"io"
"regexp"
"strconv"
"testing"
"time"

Expand Down Expand Up @@ -45,7 +43,6 @@ func TestKprobeGoCounter(t *testing.T) {
require.NoError(t, err)
goKprobeCounterPod := pods.Items[0]

want := regexp.MustCompile(`Kprobe count: ([0-9]+)`)
req := env.Cluster().Client().CoreV1().Pods(kprobeGoCounterUserspaceNs).GetLogs(goKprobeCounterPod.Name, &corev1.PodLogOptions{})
require.Eventually(t, func() bool {
logs, err := req.Stream(ctx)
Expand All @@ -56,15 +53,6 @@ func TestKprobeGoCounter(t *testing.T) {
require.NoError(t, err)
t.Logf("counter pod log %s", output.String())

matches := want.FindAllStringSubmatch(output.String(), -1)
if len(matches) >= 1 && len(matches[0]) >= 2 {
count, err := strconv.Atoi(matches[0][1])
require.NoError(t, err)
if count > 0 {
t.Logf("counted %d kprobe executions so far, BPF program is functioning", count)
return true
}
}
return false
return doKprobeCheck(t, output)
}, 30*time.Second, time.Second)
}
7 changes: 2 additions & 5 deletions test/integration/tc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"bytes"
"context"
"io"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -54,9 +53,7 @@ func TestTcGoCounter(t *testing.T) {
_, err = io.Copy(output, logs)
require.NoError(t, err)
t.Logf("counter pod log %s", output.String())
if strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
return true
}
return false

return doTcCheck(t, output)
}, 30*time.Second, time.Second)
}
15 changes: 1 addition & 14 deletions test/integration/tracepoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"bytes"
"context"
"io"
"regexp"
"strconv"
"testing"
"time"

Expand Down Expand Up @@ -45,7 +43,6 @@ func TestTracepointGoCounter(t *testing.T) {
require.NoError(t, err)
goTracepointCounterPod := pods.Items[0]

want := regexp.MustCompile(`SIGUSR1 signal count: ([0-9]+)`)
req := env.Cluster().Client().CoreV1().Pods(tracepointGoCounterUserspaceNs).GetLogs(goTracepointCounterPod.Name, &corev1.PodLogOptions{})
require.Eventually(t, func() bool {
logs, err := req.Stream(ctx)
Expand All @@ -55,16 +52,6 @@ func TestTracepointGoCounter(t *testing.T) {
_, err = io.Copy(output, logs)
require.NoError(t, err)
t.Logf("counter pod log %s", output.String())

matches := want.FindAllStringSubmatch(output.String(), -1)
if len(matches) >= 1 && len(matches[0]) >= 2 {
count, err := strconv.Atoi(matches[0][1])
require.NoError(t, err)
if count > 0 {
t.Logf("counted %d SIGUSR1 signals so far, BPF program is functioning", count)
return true
}
}
return false
return doTracepointCheck(t, output)
}, 30*time.Second, time.Second)
}
15 changes: 1 addition & 14 deletions test/integration/uprobe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"bytes"
"context"
"io"
"regexp"
"strconv"
"testing"
"time"

Expand Down Expand Up @@ -64,7 +62,6 @@ func TestUprobeGoCounter(t *testing.T) {
require.NoError(t, err)
goUprobeCounterPod := pods.Items[0]

want := regexp.MustCompile(`Uprobe count: ([0-9]+)`)
req := env.Cluster().Client().CoreV1().Pods(uprobeGoCounterUserspaceNs).GetLogs(goUprobeCounterPod.Name, &corev1.PodLogOptions{})
require.Eventually(t, func() bool {
logs, err := req.Stream(ctx)
Expand All @@ -74,16 +71,6 @@ func TestUprobeGoCounter(t *testing.T) {
_, err = io.Copy(output, logs)
require.NoError(t, err)
t.Logf("counter pod log %s", output.String())

matches := want.FindAllStringSubmatch(output.String(), -1)
if len(matches) >= 1 && len(matches[0]) >= 2 {
count, err := strconv.Atoi(matches[0][1])
require.NoError(t, err)
if count > 0 {
t.Logf("counted %d uprobe executions so far, BPF program is functioning", count)
return true
}
}
return false
return doUprobeCheck(t, output)
}, 30*time.Second, time.Second)
}
7 changes: 2 additions & 5 deletions test/integration/xdp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"encoding/base64"
"io"
"os"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -136,9 +135,7 @@ func TestXdpGoCounter(t *testing.T) {
_, err = io.Copy(output, logs)
require.NoError(t, err)
t.Logf("counter pod log %s", output.String())
if strings.Contains(output.String(), "packets received") && strings.Contains(output.String(), "bytes received") {
return true
}
return false

return doXdpCheck(t, output)
}, 30*time.Second, time.Second)
}

0 comments on commit 40f93c8

Please sign in to comment.