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

Added e2e ci #36

Merged
merged 5 commits into from
Mar 20, 2023
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
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())
})
}