Skip to content

Commit

Permalink
Add test against cda cluster to validate sfc behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
bn222 committed Oct 31, 2024
1 parent a185e0f commit 5d403fe
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 21 deletions.
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,15 @@ check-podman:

.PHONY: test
test: podman-check manifests generate fmt vet envtest ginkgo
FAST_TEST=false KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) --repeat 4 $(if $(TEST_FOCUS),-focus $(TEST_FOCUS),) ./... -coverprofile cover.out
FAST_TEST=false KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) --repeat 4 $(if $(TEST_FOCUS),-focus $(TEST_FOCUS),) ./internal/... -coverprofile cover.out

.PHONY: test
.PHONY: fast-test
fast-test: envtest ginkgo
FAST_TEST=true KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) $(if $(TEST_FOCUS),-focus $(TEST_FOCUS),) ./... -coverprofile cover.out
FAST_TEST=true KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) $(if $(TEST_FOCUS),-focus $(TEST_FOCUS),) ./internal/... -coverprofile cover.out
##@ Build
.PHONY: aaaa
aaaa: envtest ginkgo
FAST_TEST=true KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) $(if $(TEST_FOCUS),-focus $(TEST_FOCUS),) ./e2e-test/... -coverprofile cover.out
##@ Build

.PHONY: build
Expand Down
4 changes: 2 additions & 2 deletions dpu-cni/pkgs/cniserver/cniserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ var _ = g.Describe("Cniserver", func() {
listener net.Listener
addHandlerCalled bool
delHandlerCalled bool
testCluster testutils.TestCluster
testCluster testutils.KindCluster
)

g.BeforeEach(func() {
testCluster = testutils.TestCluster{Name: "dpu-operator-test-cluster"}
testCluster = testutils.KindCluster{Name: "dpu-operator-test-cluster"}
testCluster.EnsureExists()
})

Expand Down
138 changes: 138 additions & 0 deletions e2e-test/e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package daemon

import (
"context"
"testing"
"time"

g "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

//+kubebuilder:scaffold:imports
configv1 "github.com/openshift/dpu-operator/api/v1"
"github.com/openshift/dpu-operator/internal/testutils"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.

var (
cfg *rest.Config
testEnv *envtest.Environment
timeout = 10 * time.Second
interval = 1 * time.Second
)

func TestControllers(t *testing.T) {
RegisterFailHandler(g.Fail)

g.RunSpecs(t, "e2e tests")
}

var _ = g.BeforeSuite(func() {
logf.SetLogger(zap.New(zap.WriteTo(g.GinkgoWriter), zap.UseDevMode(true)))
})

var _ = g.AfterSuite(func() {
// Nothing needed
})

func getPod(c client.Client, name, namespace string) *corev1.Pod {
podList := &corev1.PodList{}
err := c.List(context.TODO(), podList, client.InNamespace(namespace))
Expect(err).NotTo(HaveOccurred())
for _, pod := range podList.Items {
if pod.Name == name {
return &pod
}
}
return nil
}

var _ = g.Describe("Dpu side", g.Ordered, func() {
var (
err error
dpuSideClient client.Client
)

g.BeforeEach(func() {
cluster := testutils.CdaCluster{
Name: "",
HostConfigPath: "hack/cluster-configs/config-dpu-host.yaml",
DpuConfigPath: "hack/cluster-configs/config-dpu.yaml",
}
_, dpuConfig, _ := cluster.EnsureExists()
Expect(err).NotTo(HaveOccurred())

scheme := runtime.NewScheme()
utilruntime.Must(configv1.AddToScheme(scheme))
utilruntime.Must(clientgoscheme.AddToScheme(scheme))

dpuSideClient, err = client.New(dpuConfig, client.Options{Scheme: scheme})
Expect(err).NotTo(HaveOccurred())
})

g.AfterEach(func() {
})

_ = testutils.CdaCluster{Name: "ocpcluster"}

g.It("Should create a pod when creating an SFC and there is no pod", func() {
nfName := "example-nf"
nfImage := "example-nf-image-url"
ns := "openshift-dpu-operator"

Eventually(func() bool {
return getPod(dpuSideClient, nfName, ns) != nil
}, timeout, interval).Should(BeFalse())

sfc := &configv1.ServiceFunctionChain{
ObjectMeta: metav1.ObjectMeta{
Name: "sfc-test",
Namespace: ns,
},
Spec: configv1.ServiceFunctionChainSpec{
NetworkFunctions: []configv1.NetworkFunction{
{
Name: nfName,
Image: nfImage,
},
},
},
}
err := dpuSideClient.Create(context.TODO(), sfc)
Expect(err).NotTo(HaveOccurred())

podList := &corev1.PodList{}
err = dpuSideClient.List(context.TODO(), podList, client.InNamespace(ns))
Expect(err).NotTo(HaveOccurred())

Eventually(func() bool {
pod := getPod(dpuSideClient, nfName, ns)
if pod != nil {
println("Pod got")
return pod.Spec.Containers[0].Image == nfImage
}
println("pod not there")
return false
}, timeout, interval).Should(BeTrue())

err = dpuSideClient.Delete(context.TODO(), sfc)
Expect(err).NotTo(HaveOccurred())

Eventually(func() bool {
return getPod(dpuSideClient, nfName, ns) != nil
}, timeout, interval).Should(BeFalse())
})
})
4 changes: 2 additions & 2 deletions internal/controller/dpuoperatorconfig_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,14 @@ var _ = Describe("Main Controller", Ordered, func() {
var ctx context.Context
var wg sync.WaitGroup
var mgr ctrl.Manager
var testCluster testutils.TestCluster
var testCluster testutils.KindCluster

BeforeAll(func() {
opts := zap.Options{
Development: true,
}
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
testCluster = testutils.TestCluster{Name: testClusterName}
testCluster = testutils.KindCluster{Name: testClusterName}
client := testCluster.EnsureExists()
ctx, cancel = context.WithCancel(context.Background())
wg = sync.WaitGroup{}
Expand Down
4 changes: 2 additions & 2 deletions internal/daemon/dpudaemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ var _ = g.Describe("DPU Daemon", Ordered, func() {
var (
dpuDaemon *DpuDaemon
config *rest.Config
testCluster testutils.TestCluster
testCluster testutils.KindCluster
client client.Client
)
g.BeforeEach(func() {
testCluster = testutils.TestCluster{Name: "dpu-operator-test-cluster"}
testCluster = testutils.KindCluster{Name: "dpu-operator-test-cluster"}
config = testCluster.EnsureExists()

pathManager := *utils.NewPathManager(testCluster.TempDirPath())
Expand Down
4 changes: 2 additions & 2 deletions internal/daemon/hostdaemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ var _ = g.Describe("Host Daemon", func() {
err error
fakeDpuDaemon *DummyDpuDaemon
hostDaemon *HostDaemon
testCluster *testutils.TestCluster
testCluster *testutils.KindCluster
pathManager *utils.PathManager
)
g.BeforeEach(func() {
testCluster = &testutils.TestCluster{Name: "dpu-operator-test-cluster"}
testCluster = &testutils.KindCluster{Name: "dpu-operator-test-cluster"}
testCluster.EnsureExists()
pathManager = utils.NewPathManager(testCluster.TempDirPath())
Expect(err).NotTo(HaveOccurred())
Expand Down
62 changes: 62 additions & 0 deletions internal/testutils/cdacluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package testutils

import (
"os"

"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)

type CdaCluster struct {
Name string
HostConfigPath string
DpuConfigPath string
}

func (t *CdaCluster) EnsureExists() (*rest.Config, *rest.Config, error) {
hostConfig, err := t.createClient("/root/kubeconfig.ocpcluster")
if err != nil {
return nil, nil, err
}
dpuConfig, err := t.createClient("/root/kubeconfig.microshift")
if err != nil {
return nil, nil, err
}
return hostConfig, dpuConfig, nil
}

func (t *CdaCluster) createClient(kubeconfigPath string) (*rest.Config, error) {
kubeconfig, err := readToByte(kubeconfigPath)
if err != nil {
return nil, err
}
config, err := clientcmd.NewClientConfigFromBytes(kubeconfig)
if err != nil {
return nil, err
}
restCfg, err := config.ClientConfig()
if err != nil {
return nil, err
}
return restCfg, nil
}

func readToByte(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()

stats, err := f.Stat()
if err != nil {
return nil, err
}

cfg := make([]byte, stats.Size())
_, err = f.Read(cfg)
if err != nil {
return nil, err
}
return cfg, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ func bootstrapTestEnv(restConfig *rest.Config) {
Expect(cfg).NotTo(BeNil())
}

type TestCluster struct {
type KindCluster struct {
Name string
}

func (t *TestCluster) TempDirPath() string {
func (t *KindCluster) TempDirPath() string {
return filepath.Join("/tmp", t.Name)
}

func (t *TestCluster) ensureTempDir() error {
func (t *KindCluster) ensureTempDir() error {
dirPath := t.TempDirPath()
_, err := os.Stat(dirPath)
if err == nil {
Expand All @@ -86,7 +86,7 @@ func (t *TestCluster) ensureTempDir() error {
return err
}

func (t *TestCluster) ensureTempDirDeleted() error {
func (t *KindCluster) ensureTempDirDeleted() error {
dirPath := t.TempDirPath()
err := os.RemoveAll(dirPath)
if err != nil {
Expand All @@ -95,19 +95,19 @@ func (t *TestCluster) ensureTempDirDeleted() error {
return nil
}

func (t *TestCluster) EnsureExists() *rest.Config {
client := t.prepareTestCluster()
func (t *KindCluster) EnsureExists() *rest.Config {
client := t.prepareKindCluster()
bootstrapTestEnv(client)
return client
}

func (t *TestCluster) EnsureDeleted() {
deleteKindTestCluster(t.Name)
func (t *KindCluster) EnsureDeleted() {
deleteKindCluster(t.Name)
err := t.ensureTempDirDeleted()
Expect(err).NotTo(HaveOccurred())
}

func deleteKindTestCluster(name string) {
func deleteKindCluster(name string) {
provider := cluster.NewProvider()
provider.Delete(name, "")
}
Expand Down Expand Up @@ -148,7 +148,7 @@ func clusterExists(p *cluster.Provider, name string) bool {
return false
}

func (t *TestCluster) prepareTestCluster() *rest.Config {
func (t *KindCluster) prepareKindCluster() *rest.Config {
var cfg []byte
var err error

Expand Down
10 changes: 10 additions & 0 deletions internal/testutils/testcluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package testutils

import (
"k8s.io/client-go/rest"
)

type Cluster interface {
EnsureExists() *rest.Config
EnsureDeleted()
}

0 comments on commit 5d403fe

Please sign in to comment.