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

creating a unit test using mocking for the generate SS function #20

Closed
wants to merge 13 commits into from
Closed
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ EXECUTABLE := commatrix-gen
.DEFAULT_GOAL := run

build:
go build -o $(EXECUTABLE) $(GO_SRC)
go build -o $(EXECUTABLE) $(GO_SRC)

mock-generate:
go generate ./...

oc:
ifeq (, $(shell which oc))
Expand Down
11 changes: 10 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import (
"os"
"path/filepath"

"github.com/openshift-kni/commatrix/debug"

clientutil "github.com/openshift-kni/commatrix/client"

"github.com/openshift-kni/commatrix/commatrix"
)

Expand Down Expand Up @@ -33,6 +37,10 @@ func main() {
if !ok {
panic("must set the KUBECONFIG environment variable")
}
cs, err := clientutil.New(kubeconfig)
if err != nil {
panic("must set the KUBECONFIG environment variable")
}

var env commatrix.Env
switch envStr {
Expand Down Expand Up @@ -68,7 +76,8 @@ func main() {
panic(fmt.Sprintf("Error while writing the endpoint slice matrix to file :%v", err))
}
// generate the ss matrix and ss raws
ssMat, ssOutTCP, ssOutUDP, err := commatrix.GenerateSS(kubeconfig, customEntriesPath, customEntriesFormat, format, env, deployment, destDir)
newDebugPod := &debug.NewDebugPod{}
ssMat, ssOutTCP, ssOutUDP, err := commatrix.GenerateSS(cs, newDebugPod)
if err != nil {
panic(fmt.Sprintf("Error while generating the ss matrix and ss raws :%v", err))
}
Expand Down
79 changes: 78 additions & 1 deletion commatrix/commatrix_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package commatrix

import (
"context"
"fmt"
"path/filepath"
"strings"
"testing"
"time"

gomock "go.uber.org/mock/gomock"

"github.com/openshift-kni/commatrix/types"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"

clientutil "github.com/openshift-kni/commatrix/client"
"github.com/openshift-kni/commatrix/debug"
"github.com/openshift-kni/commatrix/types"
)

func TestGetPrintFunction(t *testing.T) {
Expand Down Expand Up @@ -50,3 +61,69 @@ func TestWriteMatrixToFile(t *testing.T) {
assert.NoError(t, err)
assert.FileExists(t, filepath.Join(destDir, "test-matrix.json"))
}

func TestGenerateSS(t *testing.T) {
fakeClientset := fake.NewSimpleClientset()
clientset := &clientutil.ClientSet{
CoreV1Interface: fakeClientset.CoreV1(),
}

ctrlTest := gomock.NewController(t)
defer ctrlTest.Finish()

mockDebugPod := debug.NewMockDebugPodInterface(ctrlTest)
NewmockDebugPod := debug.NewMockNewDebugPodInterface(ctrlTest)

tcpOutput := []byte(`LISTEN 0 4096 127.0.0.1:8797 0.0.0.0:* users:(("machine-config-",pid=3534,fd=3))
LISTEN 0 4096 127.0.0.1:8798 0.0.0.0:* users:(("machine-config-",pid=3534,fd=13))
LISTEN 0 4096 127.0.0.1:9100 0.0.0.0:* users:(("node_exporter",pid=4147,fd=3))`)

udpOutput := []byte(`UNCONN 0 0 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=1399,fd=5),("systemd",pid=1,fd=78))
UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=1015,fd=5))
UNCONN 0 0 10.46.97.104:500 0.0.0.0:* users:(("pluto",pid=2115,fd=21))`)
Output := []byte(`1: /system.slice/containerd.service
2: /system.slice/kubelet.service
3: /system.slice/sshd.service`)

// Set up the expectations
mockDebugPod.EXPECT().ExecWithRetry(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
func(cmd string, interval, duration time.Duration) ([]byte, error) {
if strings.HasPrefix(cmd, "cat /proc/") && strings.Contains(cmd, "/cgroup") {
return Output, nil
}
if cmd == "ss -anpltH" {
return tcpOutput, nil
}
if cmd == "ss -anpluH" {
return udpOutput, nil
}
return nil, fmt.Errorf("unknown command")
},
).AnyTimes()

mockDebugPod.EXPECT().Clean().Return(nil).AnyTimes()
mockDebugPod.EXPECT().GetNodeName().Return("test-node").AnyTimes()

NewmockDebugPod.EXPECT().New(clientset, "test-node", "openshift-commatrix-debug", "quay.io/openshift-release-dev/ocp-release:4.15.12-multi").Return(mockDebugPod, nil)

testNode := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "test-node",
},
}
_, _ = clientset.CoreV1Interface.Nodes().Create(context.TODO(), testNode, metav1.CreateOptions{})

ssMat, ssOutTCP, ssOutUDP, err := GenerateSS(clientset, NewmockDebugPod)

// Pass the expected ClientSet to GenerateSS
expectedSSMat := &types.ComMatrix{
Matrix: []types.ComDetails{
{Direction: "Ingress", Protocol: "UDP", Port: 111, Namespace: "", Service: "rpcbind", Pod: "", Container: "", NodeRole: "", Optional: false},
{Direction: "Ingress", Protocol: "UDP", Port: 500, Namespace: "", Service: "pluto", Pod: "", Container: "", NodeRole: "", Optional: false},
}}

assert.NoError(t, err)
assert.Equal(t, expectedSSMat, ssMat, "Expected and actual ssMat values should match")
assert.Equal(t, "node: test-node\nLISTEN 0 4096 127.0.0.1:8797 0.0.0.0:* users:((\"machine-config-\",pid=3534,fd=3)) \nLISTEN 0 4096 127.0.0.1:8798 0.0.0.0:* users:((\"machine-config-\",pid=3534,fd=13)) \nLISTEN 0 4096 127.0.0.1:9100 0.0.0.0:* users:((\"node_exporter\",pid=4147,fd=3))\n", string(ssOutTCP))
assert.Equal(t, "node: test-node\nUNCONN 0 0 0.0.0.0:111 0.0.0.0:* users:((\"rpcbind\",pid=1399,fd=5),(\"systemd\",pid=1,fd=78))\nUNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:((\"chronyd\",pid=1015,fd=5)) \nUNCONN 0 0 10.46.97.104:500 0.0.0.0:* users:((\"pluto\",pid=2115,fd=21))\n", string(ssOutUDP))
}
15 changes: 5 additions & 10 deletions commatrix/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ import (
"github.com/openshift-kni/commatrix/types"
)

func GenerateSS(kubeconfig, customEntriesPath, customEntriesFormat, format string, env Env, deployment Deployment, destDir string) (ssMat *types.ComMatrix, ssOutTCP, ssOutUDP []byte, err error) {
cs, err := clientutil.New(kubeconfig)
if err != nil {
return nil, nil, nil, err
}

func GenerateSS(cs *clientutil.ClientSet, debugPod debug.NewDebugPodInterface) (ssMat *types.ComMatrix, ssOutTCP, ssOutUDP []byte, err error) {
nodesList, err := cs.CoreV1Interface.Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, nil, nil, err
Expand All @@ -46,18 +41,18 @@ func GenerateSS(kubeconfig, customEntriesPath, customEntriesFormat, format strin
for _, n := range nodesList.Items {
node := n
g.Go(func() error {
debugPod, err := debug.New(cs, node.Name, consts.DefaultDebugNamespace, consts.DefaultDebugPodImage)
newdebugPod, err := debugPod.New(cs, node.Name, consts.DefaultDebugNamespace, consts.DefaultDebugPodImage)
if err != nil {
return err
}
defer func() {
err := debugPod.Clean()
err := newdebugPod.Clean()
if err != nil {
fmt.Printf("failed cleaning debug pod %s: %v", debugPod, err)
fmt.Printf("failed cleaning debug pod %s: %v", newdebugPod, err)
}
}()

cds, ssTCP, ssUDP, err := ss.CreateSSOutputFromNode(debugPod, &node)
cds, ssTCP, ssUDP, err := ss.CreateSSOutputFromNode(newdebugPod, &node)
if err != nil {
return err
}
Expand Down
21 changes: 20 additions & 1 deletion debug/debug.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package debug

//go:generate mockgen -destination=debug_mock.go -package=debug . DebugPodInterface
//go:generate mockgen -destination=new_debug_mock.go -package=debug . NewDebugPodInterface

import (
"context"
"errors"
Expand All @@ -17,20 +20,36 @@ import (
"github.com/openshift-kni/commatrix/client"
)

type DebugPodInterface interface {
aabughosh marked this conversation as resolved.
Show resolved Hide resolved
ExecWithRetry(command string, interval time.Duration, duration time.Duration) ([]byte, error)
Clean() error
GetNodeName() string
}

type NewDebugPodInterface interface {
New(cs *client.ClientSet, node string, namespace string, image string) (DebugPodInterface, error)
}

type NewDebugPod struct{}

type DebugPod struct {
Name string
Namespace string
NodeName string
}

func (dp *DebugPod) GetNodeName() string {
return dp.NodeName
}

const (
interval = 1 * time.Second
timeout = 2 * time.Minute
)

// New creates debug pod on the given node, puts it in infinite sleep,
// and returns the DebugPod object. Use the Clean() method to delete it.
func New(cs *client.ClientSet, node string, namespace string, image string) (*DebugPod, error) {
func (n *NewDebugPod) New(cs *client.ClientSet, node string, namespace string, image string) (DebugPodInterface, error) {
if namespace == "" {
return nil, errors.New("failed creating new debug pod: got empty namespace")
}
Expand Down
83 changes: 83 additions & 0 deletions debug/debug_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions debug/new_debug_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ go 1.21

require (
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a
github.com/golang/mock v1.6.0
github.com/openshift/client-go v0.0.0-20240415214935-be70f772f157
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
go.uber.org/mock v0.4.0
k8s.io/api v0.29.3
k8s.io/apimachinery v0.29.3
k8s.io/client-go v0.29.3
Expand All @@ -16,6 +18,7 @@ require (
)

require (
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/openshift/api v0.0.0-20240415161129-d7aff303fa1a // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
)
Expand Down
Loading
Loading