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

Unit Test for FAR Controller #11

Merged
merged 10 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from 9 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
21 changes: 14 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ OPM_VERSION ?= v1.26.2
OPERATOR_SDK_VERSION ?= v1.26.0
# See https://github.com/slintes/sort-imports/releases for the last version
SORT_IMPORTS_VERSION = v0.1.0
# See https://github.com/onsi/ginkgo/releases for the last version
GINKGO_VERSION ?= v1.16.5
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.23

# IMAGE_REGISTRY used to indicate the registery/group for the operator, bundle and catalog
IMAGE_REGISTRY ?= quay.io/medik8s
Expand Down Expand Up @@ -90,9 +94,6 @@ ifeq ($(USE_IMAGE_DIGESTS), true)
BUNDLE_GEN_FLAGS += --use-image-digests
endif

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.23

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
Expand Down Expand Up @@ -174,8 +175,8 @@ fix-imports: sort-imports
test: test-no-verify verify-unchanged ## Generate and format code, run tests, generate manifests and bundle, and verify no uncommitted changes

.PHONY: test-no-verify
test-no-verify: manifests generate go-verify fmt vet envtest # Generate and format code, and run tests
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out
test-no-verify: manifests generate go-verify fmt vet envtest ginkgo # Generate and format code, and run tests
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(ENVTEST_DIR)/$(ENVTEST_VERSION) -p path)" $(GINKGO) -v -r --keepGoing -requireSuite -coverprofile cover.out

##@ Build

Expand Down Expand Up @@ -242,6 +243,7 @@ $(LOCALBIN):
KUSTOMIZE_DIR ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN_DIR ?= $(LOCALBIN)/controller-gen
ENVTEST_DIR ?= $(LOCALBIN)/setup-envtest
GINKGO_DIR ?= $(LOCALBIN)/ginkgo
OPM_DIR = $(LOCALBIN)/opm
OPERATOR_SDK_DIR ?= $(LOCALBIN)/operator-sdk
SORT_IMPORTS_DIR ?= $(LOCALBIN)/sort-imports
Expand All @@ -250,6 +252,7 @@ SORT_IMPORTS_DIR ?= $(LOCALBIN)/sort-imports
KUSTOMIZE = $(KUSTOMIZE_DIR)/$(KUSTOMIZE_VERSION)/kustomize
CONTROLLER_GEN = $(CONTROLLER_GEN_DIR)/$(CONTROLLER_GEN_VERSION)/controller-gen
ENVTEST = $(ENVTEST_DIR)/$(ENVTEST_VERSION)/setup-envtest
GINKGO = $(GINKGO_DIR)/$(GINKGO_VERSION)/ginkgo
OPM = $(OPM_DIR)/$(OPM_VERSION)/opm
OPERATOR_SDK = $(OPERATOR_SDK_DIR)/$(OPERATOR_SDK_VERSION)/operator-sdk
SORT_IMPORTS = $(SORT_IMPORTS_DIR)/$(SORT_IMPORTS_VERSION)/sort-imports
Expand All @@ -262,10 +265,14 @@ kustomize: ## Download kustomize locally if necessary.
controller-gen: ## Download controller-gen locally if necessary.
$(call go-install-tool,$(CONTROLLER_GEN),$(CONTROLLER_GEN_DIR),sigs.k8s.io/controller-tools/cmd/controller-gen@${CONTROLLER_GEN_VERSION})

.PHONY: envtest
.PHONY: envtest ## This library helps write integration tests for your controllers by setting up and starting an instance of etcd and the Kubernetes API server, without kubelet, controller-manager or other components.
envtest: ## Download envtest-setup locally if necessary.
$(call go-install-tool,$(ENVTEST),$(ENVTEST_DIR),sigs.k8s.io/controller-runtime/tools/setup-envtest@${ENVTEST_VERSION})

.PHONY: ginkgo
ginkgo: ## Download ginkgo locally if necessary.
$(call go-install-tool,$(GINKGO),$(GINKGO_DIR),github.com/onsi/ginkgo/ginkgo@${GINKGO_VERSION})

.PHONY: sort-imports
sort-imports: ## Download sort-imports locally if necessary.
$(call go-install-tool,$(SORT_IMPORTS),$(SORT_IMPORTS_DIR),github.com/slintes/sort-imports@$(SORT_IMPORTS_VERSION))
Expand Down Expand Up @@ -324,7 +331,7 @@ endef

.PHONY: build-tools
build-tools: ## Download & build all the tools locally if necessary.
$(MAKE) kustomize controller-gen envtest opm operator-sdk
$(MAKE) kustomize controller-gen envtest ginkgo opm operator-sdk

# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image.
ifneq ($(origin CATALOG_BASE_IMG), undefined)
Expand Down
49 changes: 34 additions & 15 deletions controllers/suite_test.go → controllers/controllers_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
Copyright 2022.

Copyright 2023.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -17,51 +16,53 @@ limitations under the License.
package controllers

import (
"context"
"path/filepath"
"testing"

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

"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"

//+kubebuilder:scaffold:imports ## https://github.com/kubernetes-sigs/kubebuilder/issues/1487 ?
fenceagentsv1alpha1 "github.com/medik8s/fence-agents-remediation/api/v1alpha1"
//+kubebuilder:scaffold:imports
)

// 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
var k8sClient client.Client
var k8sManager manager.Manager
var testEnv *envtest.Environment
var ctx context.Context
var cancel context.CancelFunc
var mocksExecuter *mockExecuter

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

RunSpecsWithDefaultAndCustomReporters(t,
"Controller Suite",
[]Reporter{printer.NewlineReporter{}})
RunSpecs(t, "Controllers Suite")
}

var _ = BeforeSuite(func() {
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
opts := zap.Options{
Development: true,
}
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseFlagOptions(&opts)))

By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: true,
}

var err error
// cfg is defined in this file globally.
cfg, err = testEnv.Start()
cfg, err := testEnv.Start()
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())

Expand All @@ -70,14 +71,32 @@ var _ = BeforeSuite(func() {

//+kubebuilder:scaffold:scheme

k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())
mocksExecuter = newMockExecuter()
err = (&FenceAgentsRemediationReconciler{
Client: k8sClient,
Log: k8sManager.GetLogger().WithName("test far reconciler"),
Scheme: k8sManager.GetScheme(),
Executor: mocksExecuter,
}).SetupWithManager(k8sManager)
Expect(err).NotTo(HaveOccurred())

go func() {
// https://github.com/kubernetes-sigs/controller-runtime/issues/1571
ctx, cancel = context.WithCancel(ctrl.SetupSignalHandler())
err := k8sManager.Start(ctx)
Expect(err).NotTo(HaveOccurred())
}()
}, 60)

var _ = AfterSuite(func() {
By("tearing down the test environment")
cancel()
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
})
18 changes: 5 additions & 13 deletions controllers/fenceagentsremediation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ var (
// FenceAgentsRemediationReconciler reconciles a FenceAgentsRemediation object
type FenceAgentsRemediationReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Log logr.Logger
Scheme *runtime.Scheme
Executor cli.Executer
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -91,23 +92,16 @@ func (r *FenceAgentsRemediationReconciler) Reconcile(ctx context.Context, req ct
if err != nil {
return emptyResult, err
}

// Build CLI executer for FAR's pod
r.Log.Info("Build CLI executer for FAR's pod")
ex, err := cli.NewExecuter(pod)
if err != nil {
return emptyResult, err
}

//TODO: Check that FA is excutable? run cli.IsExecuteable

r.Log.Info("Create and execute the fence agent", "Fence Agent", far.Spec.Agent)
faParams, err := buildFenceAgentParams(far)
if err != nil {
return emptyResult, err
}
cmd := append([]string{far.Spec.Agent}, faParams...)
// The Fence Agent is excutable and the parameters are valid but we don't know about their values
if _, _, err := ex.Execute(cmd); err != nil {
if _, _, err := r.Executor.Execute(pod, cmd); err != nil {
//TODO: better seperation between errors from wrong shared parameters values and wrong node parameters values
return emptyResult, err
}
Expand All @@ -128,7 +122,6 @@ func (r *FenceAgentsRemediationReconciler) getFenceAgentsPod(namespace string) (
}
if err := r.Client.List(context.Background(), pods, &options); err != nil {
r.Log.Error(err, "failed fetching Fence Agent layer pod")
// err := errors.New("failed fetching Fence Agent layer pod")
return nil, err
}
if len(pods.Items) == 0 {
Expand All @@ -141,7 +134,6 @@ func (r *FenceAgentsRemediationReconciler) getFenceAgentsPod(namespace string) (
return nil, podNotFoundErr
}
return &pods.Items[0], nil

}

// buildFenceAgentParams collects the FAR's parameters for the node based on FAR CR
Expand Down
Loading