Skip to content

Commit

Permalink
Merge pull request #36 from srl-labs/e2e-tests
Browse files Browse the repository at this point in the history
Added e2e ci
  • Loading branch information
hellt authored Mar 20, 2023
2 parents 2a9ba02 + d866288 commit c42d638
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 15 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}
- name: Test
Expand All @@ -37,7 +37,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-go@v3
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}
- name: golangci-lint
Expand All @@ -54,7 +54,7 @@ jobs:
- test
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}

Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ name: E2E
kne_ref:
description: "openconfig/kne reference (tag, commit, branch)"
type: string
default: v0.1.8
default: v0.1.9
required: true
kind_version:
description: "KinD version"
Expand All @@ -28,19 +28,23 @@ jobs:
echo "KNE_REF=${{ inputs.kne_ref }}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}

- name: Install kind
uses: engineerd/setup-kind@v0.5.0
with:
name: srl-test # cluster name
version: ${{ inputs.kind_version }}
skipClusterCreation: true

- uses: actions/checkout@v3

- name: Run e2e test
- name: Prepare e2e environment
run: make prepare-e2e-env

- name: Run e2e tests
# this test ensures that srl-controller (built from referenced source) can be succesfully installed on a KNE cluster
# for a using specified versions of KNE/KinD
run: make install-srl-controller
run: make test-e2e
17 changes: 15 additions & 2 deletions .mk/e2e.mk
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# KNE_REF is a git reference to use for KNE. It can be a branch, tag, or commit hash.
KNE_REF ?= v0.1.8
KNE_REF ?= v0.1.9
KNE_REPO := https://github.com/openconfig/kne.git
KNE_TEMP_DIR := /tmp/.srlcontroller-tests/kne
KNE_TEST_DEPLOYMENT_FILE := ${KNE_TEMP_DIR}/deploy/kne/kind-bridge-no-controllers.yaml
KIND_CLUSTER_NAME ?= srl-test
SRL_IMAGE ?= ghcr.io/nokia/srlinux:latest

.PHONY: install-kne
install-kne: ## Install KNE
Expand All @@ -30,7 +31,19 @@ temp-docker-build: ## Built controller container using the image and tag specifi
kind load docker-image $$image:$$tag --name ${KIND_CLUSTER_NAME}

.PHONY: install-srl-controller
install-srl-controller: install-kne kne-test-deployment-cfg-file deploy-kne temp-docker-build ## Install srl-controller from current working dir
install-srl-controller: ## Install srl-controller from current working dir
kubectl apply -k config/default
@echo "wait for controller manager to be ready"
kubectl -n srlinux-controller wait --for=condition=Available deployment.apps/srlinux-controller-controller-manager

.PHONY: kind-load-image
kind-load-image: ## Load SR Linux container image to kind cluster
docker pull ${SRL_IMAGE}
kind load docker-image ${SRL_IMAGE} --name srl-test

.PHONY: prepare-e2e-env
prepare-e2e-env: install-kne kne-test-deployment-cfg-file deploy-kne temp-docker-build install-srl-controller kind-load-image ## Install srl-controller from current working dir

.PHONY: test-e2e
test-e2e: ## Test e2e using kind
go test -v github.com/srl-labs/srl-controller/tests/e2e
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ vet: ## Run go vet against code.

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverpkg=./... -coverprofile cover.out
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test -coverpkg=./... -coverprofile cover.out `go list ./... | grep -v e2e`

.PHONY: unit-test
unit-test: manifests generate fmt vet ## Run unit tests which do not involve envtest.
Expand Down
5 changes: 0 additions & 5 deletions config/crd/bases/kne.srlinux.dev_srlinuxes.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Copyright 2022 Nokia
# Licensed under the BSD 3-Clause License.
# SPDX-License-Identifier: BSD-3-Clause


---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
Expand Down
56 changes: 56 additions & 0 deletions tests/e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2023 Nokia
// Licensed under the BSD 3-Clause License.
// SPDX-License-Identifier: BSD-3-Clause

package e2e_controllers_test

import (
"context"
"os"
"testing"
"time"

. "github.com/onsi/gomega"

srlinuxv1 "github.com/srl-labs/srl-controller/api/v1"
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var (
ctx context.Context
cancel context.CancelFunc
k8sClient client.Client
)

// TestMain is the entry point for the e2e tests.
// It sets up the test environment and initializes a k8s client.
func TestMain(m *testing.M) {
ctx, cancel = context.WithCancel(context.TODO())

logf.SetLogger(zap.New(zap.UseDevMode(true)))

SetDefaultEventuallyPollingInterval(100 * time.Millisecond)
SetDefaultEventuallyTimeout(10 * time.Second)

// add srlinux scheme
if err := srlinuxv1.AddToScheme(scheme.Scheme); err != nil {
panic(err)
}

var err error

k8sClient, err = client.New(ctrl.GetConfigOrDie(), client.Options{Scheme: scheme.Scheme})
if err != nil {
panic(err)
}

rc := m.Run()

cancel()

os.Exit(rc)
}
141 changes: 141 additions & 0 deletions tests/e2e/srlinux_controller_e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright 2023 Nokia
// Licensed under the BSD 3-Clause License.
// SPDX-License-Identifier: BSD-3-Clause

package e2e_controllers_test

import (
"fmt"
"testing"
"time"

. "github.com/onsi/gomega"
srlinuxv1 "github.com/srl-labs/srl-controller/api/v1"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

const (
SrlinuxNamespace = "test"
SrlinuxName = "test-srlinux"
testImageName = "ghcr.io/nokia/srlinux:latest"
defaultImageName = "ghcr.io/nokia/srlinux:latest"
srlinuxMaxStartupTime = 3 * time.Minute
)

var namespacedName = types.NamespacedName{Name: SrlinuxName, Namespace: SrlinuxNamespace}

func TestSrlinuxReconciler(t *testing.T) {
namespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: SrlinuxNamespace,
},
}

setup := func(t *testing.T, g *WithT) *corev1.Namespace {
t.Helper()

t.Log("Creating the namespace")
g.Expect(k8sClient.Create(ctx, namespace)).Should(Succeed())

return namespace
}

teardown := func(t *testing.T, _ *WithT) {
t.Helper()

t.Log("Deleting the namespace")

_ = k8sClient.Delete(ctx, namespace)
}

t.Run("Should reconcile a Srlinux custom resource", func(t *testing.T) {
g := NewWithT(t)

setup(t, g)
defer teardown(t, g)

t.Log("Checking that Srlinux resource doesn't exist in the cluster")
srlinux := &srlinuxv1.Srlinux{}

err := k8sClient.Get(ctx, namespacedName, srlinux)

g.Expect(errors.IsNotFound(err)).To(BeTrue())

t.Log("Creating the custom resource without parameters for the Kind Srlinux")
srlinux = &srlinuxv1.Srlinux{
ObjectMeta: metav1.ObjectMeta{
Name: SrlinuxName,
Namespace: SrlinuxNamespace,
},
TypeMeta: metav1.TypeMeta{
Kind: "Srlinux",
APIVersion: "kne.srlinux.dev/v1",
},
Spec: srlinuxv1.SrlinuxSpec{
Config: &srlinuxv1.NodeConfig{
Image: testImageName,
},
},
}
g.Expect(k8sClient.Create(ctx, srlinux)).Should(Succeed())

t.Log("Checking if the custom resource was successfully created")
g.Eventually(func() error {
found := &srlinuxv1.Srlinux{}

return k8sClient.Get(ctx, namespacedName, found)
}).Should(Succeed())

// Reconcile is triggered by the creation of the custom resource

t.Log("Checking if Srlinux Pod was successfully created in the reconciliation")
g.Eventually(func() error {
found := &corev1.Pod{}

return k8sClient.Get(ctx, namespacedName, found)
}).Should(Succeed())

t.Log("Ensuring the Srlinux CR Status has been updated with the default image")
g.Eventually(func() error {
g.Expect(k8sClient.Get(ctx, namespacedName, srlinux)).Should(Succeed())

if srlinux.Status.Image != defaultImageName {
return fmt.Errorf("got Srlinux.Status.Image: %s, want: %s", srlinux.Status.Image, defaultImageName)
}

return nil
}).Should(Succeed())

t.Log("Ensuring the Srlinux CR pod is running")
g.Eventually(func() bool {
found := &corev1.Pod{}

g.Expect(k8sClient.Get(ctx, namespacedName, found)).Should(Succeed())

return found.Status.Phase == corev1.PodRunning
}, srlinuxMaxStartupTime, time.Second).Should(BeTrue())

t.Log("Deleting the custom resource for the Kind Srlinux")
g.Expect(k8sClient.Delete(ctx, srlinux)).Should(Succeed())

t.Log("Checking if the custom resource was successfully deleted")
g.Eventually(func() error {
found := &srlinuxv1.Srlinux{}

return k8sClient.Get(ctx, namespacedName, found)
}).ShouldNot(Succeed())

// // Reconcile is triggered by the deletion of the custom resource

t.Log("Checking if the pod was successfully deleted")
g.Eventually(func() error {
found := &corev1.Pod{}

return k8sClient.Get(ctx, namespacedName, found)
}).ShouldNot(Succeed())
})
}

0 comments on commit c42d638

Please sign in to comment.