Skip to content

Commit

Permalink
tests(integration): Move integration tests to tests/
Browse files Browse the repository at this point in the history
Signed-off-by: Bhargav Ravuri <bhargav.ravuri@infracloud.io>
  • Loading branch information
Bhargav-InfraCloud committed Apr 6, 2024
1 parent 236a5d6 commit 427a2c6
Show file tree
Hide file tree
Showing 21 changed files with 301 additions and 168 deletions.
65 changes: 37 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,55 +70,64 @@ all: build
# http://linuxcommand.org/lc3_adv_awk.php

.PHONY: help
help: ## Display this help.
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Development

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

##@ Test

.PHONY: fmt
fmt: ## Run go fmt against code.
fmt: ## Run go fmt against code.
go fmt ./...

.PHONY: vet
vet: ## Run go vet against code.
vet: ## Run go vet against code.
go vet ./...

.PHONY: test
test: fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -v -coverprofile=coverage.out -coverpkg ./... ./...
.PHONY: test-unit
test-unit: ## Run unit tests.
go test -v -coverprofile=coverage.out `go list ./controllers/... ./pkg/... | grep -v ./pkg/mocks`

.PHONY: unit-test-coverage
unit-test-coverage: test
.PHONY: test-coverage
test-coverage: test-unit ## Run unit tests and print code coverage.
go tool cover -func coverage.out

.PHONY: test-integration
test-integration: ## Run integration tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -v -tags=integration ./...

.PHONY: test
test: fmt vet envtest test-unit test-integration ## Run all tests (fmt, vet, envtest, unit & integration).

.PHONY: test-docker
test-docker:
test-docker: ## Run all tests (fmt, vet, envtest, unit & integration) inside a Docker container.
docker build -t test -f test.Dockerfile . && docker run test

##@ Build

.PHONY: build
build: generate fmt vet ## Build manager binary.
build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go

.PHONY: docker-build
docker-build: ## Build docker image with the manager.
docker-build: ## Build docker image with the manager.
docker build -t ${IMG} .

.PHONY: docker-push
docker-push: ## Push docker image with the manager.
docker-push: ## Push docker image with the manager.
docker push ${IMG}

##@ Deployment
Expand All @@ -140,36 +149,36 @@ ifndef ignore-not-found
endif

.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -

.PHONY: uninstall
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -

.PHONY: undeploy
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -

CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
.PHONY: controller-gen
controller-gen: ## Download controller-gen locally if necessary.
controller-gen: ## Download controller-gen locally if necessary.
$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@latest)

KUSTOMIZE = $(shell pwd)/bin/kustomize
.PHONY: kustomize
kustomize: manifests ## Download kustomize locally if necessary.
kustomize: manifests ## Download kustomize locally if necessary.
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)
kustomize build config/default > deploy/kubeslice-operator.yaml

ENVTEST = $(shell pwd)/bin/setup-envtest
.PHONY: envtest
envtest: ## Download envtest-setup locally if necessary.
envtest: ## Download envtest-setup locally if necessary.
$(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)

# go-get-tool will 'go get' any package $2 and install it to $1.
Expand All @@ -187,23 +196,23 @@ rm -rf $$TMP_DIR ;\
endef

.PHONY: bundle
bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files.
bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files.
operator-sdk generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
operator-sdk bundle validate ./bundle

.PHONY: bundle-build
bundle-build: ## Build the bundle image.
bundle-build: ## Build the bundle image.
docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .

.PHONY: bundle-push
bundle-push: ## Push the bundle image.
bundle-push: ## Push the bundle image.
$(MAKE) docker-push IMG=$(BUNDLE_IMG)

.PHONY: opm
OPM = ./bin/opm
opm: ## Download opm locally if necessary.
opm: ## Download opm locally if necessary.
ifeq (,$(wildcard $(OPM)))
ifeq (,$(shell which opm 2>/dev/null))
@{ \
Expand Down Expand Up @@ -234,12 +243,12 @@ endif
# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see:
# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator
.PHONY: catalog-build
catalog-build: opm ## Build a catalog image.
catalog-build: opm ## Build a catalog image.
$(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)

# Push the catalog image.
.PHONY: catalog-push
catalog-push: ## Push a catalog image.
catalog-push: ## Push a catalog image.
$(MAKE) docker-push IMG=$(CATALOG_IMG)

# Generate events schema map
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ package cluster
import (
"context"
"errors"
"reflect"
"runtime/debug"
"testing"

hubv1alpha1 "github.com/kubeslice/apis/pkg/controller/v1alpha1"
"github.com/kubeslice/kubeslice-monitoring/pkg/metrics"
kubeslicev1beta1 "github.com/kubeslice/worker-operator/api/v1beta1"
utilmock "github.com/kubeslice/worker-operator/pkg/mocks"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -87,9 +86,7 @@ func TestGetOperatorClusterRole(t *testing.T) {
mock.IsType(&rbacv1.ClusterRole{}),
).Return(nil)
_, err := reconciler.getOperatorClusterRole(ctx)
if expected.err != err {
t.Error("Expected error:", expected.err, " but got ", err)
}
assert.ErrorIs(t, expected.err, err)
}

func TestCreateDeregisterJobPositiveScenarios(t *testing.T) {
Expand Down Expand Up @@ -194,9 +191,7 @@ func TestCreateDeregisterJobPositiveScenarios(t *testing.T) {
mock.IsType([]k8sclient.CreateOption(nil)),
).Return(nil)
err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.err != err {
t.Error("Expected error:", expected.err, " but got ", err)
}
assert.ErrorIs(t, expected.err, err)
}

func TestReconcilerFailToUpdateClusterRegistrationStatus(t *testing.T) {
Expand Down Expand Up @@ -237,9 +232,7 @@ func TestReconcilerFailToUpdateClusterRegistrationStatus(t *testing.T) {
).Return(errors.New("error updating status of deregistration on the controller"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToCreateServiceAccount(t *testing.T) {
Expand Down Expand Up @@ -295,9 +288,7 @@ func TestReconcilerFailToCreateServiceAccount(t *testing.T) {
).Return(errors.New("unable to create service account"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToFetchOperatorClusterRole(t *testing.T) {
Expand Down Expand Up @@ -363,9 +354,7 @@ func TestReconcilerFailToFetchOperatorClusterRole(t *testing.T) {
).Return(errors.New("unable to fetch operator clusterrole"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToCreateClusterRole(t *testing.T) {
Expand Down Expand Up @@ -441,9 +430,7 @@ func TestReconcilerFailToCreateClusterRole(t *testing.T) {
).Return(errors.New("unable to create cluster role"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToCreateClusterRoleBinding(t *testing.T) {
Expand Down Expand Up @@ -524,9 +511,7 @@ func TestReconcilerFailToCreateClusterRoleBinding(t *testing.T) {
).Return(errors.New("unable to create cluster rolebinding"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToCreateConfigmap(t *testing.T) {
Expand Down Expand Up @@ -621,9 +606,7 @@ func TestReconcilerFailToCreateConfigmap(t *testing.T) {
mock.IsType([]k8sclient.CreateOption(nil)),
).Return(errors.New("Unable to create configmap"))
err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToDeleteJob(t *testing.T) {
Expand Down Expand Up @@ -729,9 +712,7 @@ func TestReconcilerFailToDeleteJob(t *testing.T) {
).Return(errors.New("Unable to delete deregister job"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestReconcilerFailToCreateDeregisterJob(t *testing.T) {
Expand Down Expand Up @@ -842,64 +823,42 @@ func TestReconcilerFailToCreateDeregisterJob(t *testing.T) {
).Return(errors.New("Unable to create deregister job"))

err := reconciler.createDeregisterJob(ctx, testClusterObj)
if expected.errMsg != err.Error() {
t.Error("Expected error:", expected.errMsg, " but got ", err)
}
assert.Equal(t, expected.errMsg, err.Error())
}

func TestGetConfigmapScriptData(t *testing.T) {
data, err := getCleanupScript()
AssertNoError(t, err)
if len(data) == 0 {
t.Fatalf("unable to get configmap data")
}
assert.NoError(t, err)
assert.NotZero(t, len(data), "unable to get configmap data")
}

func TestConstructJobForClusterDeregister(t *testing.T) {
job := constructJobForClusterDeregister()
AssertEqual(t, job.Name, deregisterJobName)
AssertEqual(t, job.Namespace, ControlPlaneNamespace)
assert.Equal(t, job.Name, deregisterJobName)
assert.Equal(t, job.Namespace, ControlPlaneNamespace)
}

func TestConstructServiceAccount(t *testing.T) {
sa := constructServiceAccount()
AssertEqual(t, sa.Name, serviceAccountName)
AssertEqual(t, sa.Namespace, ControlPlaneNamespace)
assert.Equal(t, sa.Name, serviceAccountName)
assert.Equal(t, sa.Namespace, ControlPlaneNamespace)
}

func TestConstructClusterRole(t *testing.T) {
cr := constructClusterRole(testOperatorClusterRole, "random-uid")
isEqual := reflect.DeepEqual(cr.Rules, testOperatorClusterRole.Rules)
if !isEqual {
t.Fatalf("got invalid data in clusterrole Rules: got -- %q want -- %q", &cr.Rules[0], &testOperatorClusterRole.Rules[0])
}
assert.Equal(t, cr.Rules, testOperatorClusterRole.Rules)
}

func TestConstructClusterRoleBinding(t *testing.T) {
crb := constructClusterRoleBinding("random-uid")
AssertEqual(t, crb.Name, clusterRoleBindingName)
AssertEqual(t, crb.RoleRef, testClusterRoleRef)
AssertEqual(t, len(crb.Subjects), 1)
AssertEqual(t, crb.Subjects[0], testClusterRoleBindingSubject[0])
assert.Equal(t, crb.Name, clusterRoleBindingName)
assert.Equal(t, crb.RoleRef, testClusterRoleRef)
assert.Len(t, crb.Subjects, 1)
assert.Equal(t, crb.Subjects[0], testClusterRoleBindingSubject[0])
}

func TestConstructConfigMap(t *testing.T) {
data := "this is the data."
cm := constructConfigMap(data)
AssertEqual(t, cm.Data["kubeslice-cleanup.sh"], data)
}

func AssertEqual(t *testing.T, actual interface{}, expected interface{}) {
t.Helper()
if actual != expected {
t.Log("expected --", expected, "actual --", actual)
t.Fail()
}
}

func AssertNoError(t *testing.T, err error) {
t.Helper()
if err != nil {
t.Errorf("Expected No Error but got %s, Stack:\n%s", err, string(debug.Stack()))
}
assert.Equal(t, cm.Data["kubeslice-cleanup.sh"], data)
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func TestReconcilerHandleExternalDependency(t *testing.T) {
client.StatusMock.On("Update",
mock.IsType(ctx),
mock.IsType(&hubv1alpha1.Cluster{}),
mock.IsType([]k8sclient.UpdateOption(nil)),
mock.IsType([]k8sclient.SubResourceUpdateOption(nil)),
).Return(nil)
client.On("List",
mock.IsType(ctx),
Expand Down Expand Up @@ -295,7 +295,7 @@ func TestReconcilerToFailWhileCallingCreateDeregisterJob(t *testing.T) {
client.StatusMock.On("Update",
mock.IsType(ctx),
mock.IsType(&hubv1alpha1.Cluster{}),
mock.IsType([]k8sclient.UpdateOption(nil)),
mock.IsType([]k8sclient.SubResourceUpdateOption(nil)),
).Return(errors.New("error updating status of deregistration on the controller"))
client.On("Create",
mock.IsType(ctx),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ var (
testWorkerNamespace = "kubeslice-system"
)

var k8sClient k8sclient.Client

var testVPNKeyRotationObject = &hubv1alpha1.VpnKeyRotation{
ObjectMeta: metav1.ObjectMeta{
Name: testVPNKeyRotationName,
Expand Down

0 comments on commit 427a2c6

Please sign in to comment.