Skip to content

Commit

Permalink
Add some unit tests to get above coverage requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderboltsid committed Mar 8, 2024
1 parent 935ae25 commit 7c40df7
Show file tree
Hide file tree
Showing 11 changed files with 1,009 additions and 55 deletions.
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ kind-delete: ## Delete the kind cluster
##@ Build

.PHONY: build
build: generate fmt ## Build manager binary.
build: mocks generate fmt ## Build manager binary.
echo "Git commit hash: ${GIT_COMMIT_HASH}"
go build -ldflags "-X main.gitCommitHash=${GIT_COMMIT_HASH}" -o bin/manager main.go

Expand Down Expand Up @@ -299,16 +299,24 @@ prepare-local-clusterctl: manifests cluster-templates ## Prepare overide file f
env LOCAL_PROVIDER_VERSION=$(LOCAL_PROVIDER_VERSION) \
envsubst -no-unset -no-empty -no-digit < ./clusterctl.yaml > ~/.cluster-api/clusterctl.yaml

.PHONY: mocks
mocks: ## Generate mocks for the project
mockgen -destination=mocks/ctlclient/client_mock.go -package=mockctlclient sigs.k8s.io/controller-runtime/pkg/client Client
mockgen -destination=mocks/ctlclient/manager_mock.go -package=mockctlclient sigs.k8s.io/controller-runtime/pkg/manager Manager
mockgen -destination=mocks/ctlclient/cache_mock.go -package=mockctlclient sigs.k8s.io/controller-runtime/pkg/cache Cache

GOTESTPKGS = $(shell go list ./... | grep -v /mocks)

.PHONY: unit-test
unit-test: ## Run unit tests.
unit-test: mocks ## Run unit tests.
ifeq ($(EXPORT_RESULT), true)
$(eval OUTPUT_OPTIONS = | go-junit-report -set-exit-code > junit-report.xml)
endif
KUBEBUILDER_ASSETS="$(shell setup-envtest use $(ENVTEST_K8S_VERSION) --arch=amd64 -p path)" $(GOTEST) ./... $(OUTPUT_OPTIONS)
KUBEBUILDER_ASSETS="$(shell setup-envtest use $(ENVTEST_K8S_VERSION) --arch=amd64 -p path)" $(GOTEST) $(GOTESTPKGS) $(OUTPUT_OPTIONS)

.PHONY: coverage
coverage: ## Run the tests of the project and export the coverage
KUBEBUILDER_ASSETS="$(shell setup-envtest use $(ENVTEST_K8S_VERSION) --arch=amd64 -p path)" $(GOTEST) -cover -covermode=count -coverprofile=profile.cov ./...
coverage: mocks ## Run the tests of the project and export the coverage
KUBEBUILDER_ASSETS="$(shell setup-envtest use $(ENVTEST_K8S_VERSION) --arch=amd64 -p path)" $(GOTEST) -cover -covermode=count -coverprofile=profile.cov $(GOTESTPKGS)
$(GOTOOL) cover -func profile.cov
ifeq ($(EXPORT_RESULT), true)
gocov convert profile.cov | gocov-xml > coverage.xml
Expand Down
1 change: 1 addition & 0 deletions devbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"path:./hack/flakes#go-apidiff",
"path:./hack/flakes#go-mod-upgrade",
Expand Down
20 changes: 20 additions & 0 deletions devbox.lock
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,26 @@
}
}
},
"[email protected]": {
"last_modified": "2023-12-13T22:54:10Z",
"resolved": "github:NixOS/nixpkgs/fd04bea4cbf76f86f244b9e2549fca066db8ddff#mockgen",
"source": "devbox-search",
"version": "1.6.0",
"systems": {
"aarch64-darwin": {
"store_path": "/nix/store/8jsr1j1h8g3k3j5rg8vv79aviffxrfny-mockgen-1.6.0"
},
"aarch64-linux": {
"store_path": "/nix/store/34rrlc5lz43mibljdd7ai0qyi7zcq4ic-mockgen-1.6.0"
},
"x86_64-darwin": {
"store_path": "/nix/store/cj1r5vllmiq7fh4izsmlacjrdkw2h4b5-mockgen-1.6.0"
},
"x86_64-linux": {
"store_path": "/nix/store/hs49h3p9ss5f5bqv6phgsx93s4cawif2-mockgen-1.6.0"
}
}
},
"[email protected]": {
"last_modified": "2024-02-24T23:06:34Z",
"resolved": "github:NixOS/nixpkgs/9a9dae8f6319600fa9aebde37f340975cab4b8c0#yamllint",
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ require (
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/cel-go v0.17.7 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
Expand Down Expand Up @@ -136,6 +137,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.14.0 // indirect
golang.org/x/sync v0.5.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -741,6 +743,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -968,6 +972,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
Expand Down
150 changes: 100 additions & 50 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,39 @@ limitations under the License.
package main

import (
"context"
"flag"
"fmt"
"os"
"time"

"github.com/go-logr/logr"
"github.com/spf13/pflag"
"go.uber.org/zap/zapcore"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
capiflags "sigs.k8s.io/cluster-api/util/flags"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"

infrav1alpha4 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1alpha4"
infrav1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"
"github.com/nutanix-cloud-native/cluster-api-provider-nutanix/controllers"
//+kubebuilder:scaffold:imports
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
)
var scheme = runtime.NewScheme()

// gitCommitHash is the git commit hash of the code that is running.
var gitCommitHash string
Expand All @@ -65,23 +68,22 @@ const (
defaultMaxConcurrentReconciles = 10
)

func main() {
var (
enableLeaderElection bool
probeAddr string
maxConcurrentReconciles int
diagnosticsOptions capiflags.DiagnosticsOptions
)
type managerConfig struct {
enableLeaderElection bool
probeAddr string
maxConcurrentReconciles int
diagnosticsOptions capiflags.DiagnosticsOptions

logger logr.Logger
restConfig *rest.Config
}

capiflags.AddDiagnosticsOptions(pflag.CommandLine, &diagnosticsOptions)
pflag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
pflag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
pflag.IntVar(
&maxConcurrentReconciles,
"max-concurrent-reconciles",
defaultMaxConcurrentReconciles,
func parseFlags(config *managerConfig) {
capiflags.AddDiagnosticsOptions(pflag.CommandLine, &config.diagnosticsOptions)
pflag.StringVar(&config.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
pflag.BoolVar(&config.enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
pflag.IntVar(&config.maxConcurrentReconciles, "max-concurrent-reconciles", defaultMaxConcurrentReconciles,
"The maximum number of allowed, concurrent reconciles.")

opts := zap.Options{
Expand All @@ -93,29 +95,29 @@ func main() {
ctrl.SetLogger(logger)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
}

setupLog.Info("Initializing Nutanix Cluster API Infrastructure Provider", "Git Hash", gitCommitHash)
func setupLogger() logr.Logger {
return ctrl.Log.WithName("setup")
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: capiflags.GetDiagnosticsOptions(diagnosticsOptions),
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "f265110d.cluster.x-k8s.io",
})
if err != nil {
setupLog.Error(err, "unable to create manager")
os.Exit(1)
func addHealthChecks(mgr manager.Manager) error {
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
return fmt.Errorf("unable to set up health check: %w", err)

Check warning on line 106 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L106

Added line #L106 was not covered by tests
}

// Set up the context that's going to be used in controllers and for the manager.
ctx := ctrl.SetupSignalHandler()
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
return fmt.Errorf("unable to set up ready check: %w", err)

Check warning on line 110 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L110

Added line #L110 was not covered by tests
}

return nil
}

func createInformers(ctx context.Context, mgr manager.Manager) (coreinformers.SecretInformer, coreinformers.ConfigMapInformer, error) {
// Create a secret informer for the Nutanix client
clientset, err := kubernetes.NewForConfig(mgr.GetConfig())
if err != nil {
setupLog.Error(err, "unable to create clientset for management cluster")
os.Exit(1)
return nil, nil, fmt.Errorf("unable to create clientset for management cluster: %w", err)

Check warning on line 120 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L120

Added line #L120 was not covered by tests
}

informerFactory := informers.NewSharedInformerFactory(clientset, time.Minute)
Expand All @@ -129,21 +131,24 @@ func main() {
go cmInformer.Run(ctx.Done())
cache.WaitForCacheSync(ctx.Done(), cmInformer.HasSynced)

return secretInformer, configMapInformer, nil
}

func setupControllers(ctx context.Context, mgr manager.Manager, secretInformer coreinformers.SecretInformer, configMapInformer coreinformers.ConfigMapInformer, maxConcurrentReconciles int) error {
clusterCtrl, err := controllers.NewNutanixClusterReconciler(mgr.GetClient(),
secretInformer,
configMapInformer,
mgr.GetScheme(),
controllers.WithMaxConcurrentReconciles(maxConcurrentReconciles),
)
if err != nil {
setupLog.Error(err, "unable to create controller", "controller", "NutanixCluster")
os.Exit(1)
return fmt.Errorf("unable to create NutanixCluster controller: %w", err)

Check warning on line 145 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L145

Added line #L145 was not covered by tests
}

if err = clusterCtrl.SetupWithManager(ctx, mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "NutanixCluster")
os.Exit(1)
return fmt.Errorf("unable to setup NutanixCluster controller with manager: %w", err)

Check warning on line 149 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L149

Added line #L149 was not covered by tests
}

machineCtrl, err := controllers.NewNutanixMachineReconciler(
mgr.GetClient(),
secretInformer,
Expand All @@ -152,27 +157,72 @@ func main() {
controllers.WithMaxConcurrentReconciles(maxConcurrentReconciles),
)
if err != nil {
setupLog.Error(err, "unable to create controller", "controller", "NutanixMachine")
os.Exit(1)
return fmt.Errorf("unable to create NutanixMachine controller: %w", err)

Check warning on line 160 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L160

Added line #L160 was not covered by tests
}

if err = machineCtrl.SetupWithManager(ctx, mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "NutanixMachine")
os.Exit(1)
return fmt.Errorf("unable to setup NutanixMachine controller with manager: %w", err)

Check warning on line 164 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L164

Added line #L164 was not covered by tests
}
//+kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
return nil
}

func runManager(mgr manager.Manager, config *managerConfig) error {
// Set up the context that's going to be used in controllers and for the manager.
ctx := ctrl.SetupSignalHandler()
secretInformer, configMapInformer, err := createInformers(ctx, mgr)
if err != nil {
return fmt.Errorf("unable to create informers: %w", err)

Check warning on line 176 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L176

Added line #L176 was not covered by tests
}

if err = setupControllers(ctx, mgr, secretInformer, configMapInformer, config.maxConcurrentReconciles); err != nil {
return fmt.Errorf("unable to setup controllers: %w", err)

Check warning on line 180 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L180

Added line #L180 was not covered by tests
}

config.logger.Info("starting CAPX Controller Manager")
if err := mgr.Start(ctx); err != nil {
return fmt.Errorf("problem running manager: %w", err)

Check warning on line 185 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L185

Added line #L185 was not covered by tests
}

return nil
}

func initializeManager(config *managerConfig) (manager.Manager, error) {
return ctrl.NewManager(config.restConfig, ctrl.Options{
Scheme: scheme,
Metrics: capiflags.GetDiagnosticsOptions(config.diagnosticsOptions),
HealthProbeBindAddress: config.probeAddr,
LeaderElection: config.enableLeaderElection,
LeaderElectionID: "f265110d.cluster.x-k8s.io",
})
}

func main() {
logger := setupLogger()
logger.Info("Initializing Nutanix Cluster API Infrastructure Provider", "Git Hash", gitCommitHash)

Check warning on line 203 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L202-L203

Added lines #L202 - L203 were not covered by tests

restConfig := ctrl.GetConfigOrDie()

Check warning on line 205 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L205

Added line #L205 was not covered by tests

config := &managerConfig{

Check warning on line 207 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L207

Added line #L207 was not covered by tests
logger: logger,
restConfig: restConfig,
}
parseFlags(config)

Check warning on line 211 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L211

Added line #L211 was not covered by tests

mgr, err := initializeManager(config)
if err != nil {
logger.Error(err, "unable to create manager")

Check warning on line 215 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L213-L215

Added lines #L213 - L215 were not covered by tests
os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")

if err := addHealthChecks(mgr); err != nil {
logger.Error(err, "unable to add health checks to manager")

Check warning on line 220 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L219-L220

Added lines #L219 - L220 were not covered by tests
os.Exit(1)
}

setupLog.Info("starting CAPX Controller Manager")
if err := mgr.Start(ctx); err != nil {
setupLog.Error(err, "problem running manager")
if err := runManager(mgr, config); err != nil {
logger.Error(err, "problem running manager")

Check warning on line 225 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L224-L225

Added lines #L224 - L225 were not covered by tests
os.Exit(1)
}
}
Loading

0 comments on commit 7c40df7

Please sign in to comment.