Skip to content

Commit

Permalink
Add unit tests for k8s install and uninstall components of agent reco…
Browse files Browse the repository at this point in the history
…nciler (#388)

Add unit tests for the installK8sComponents and uninstallk8sComponents functions within reconcile.
However, since these functions deal with the actual installation of the k8s components, the Install() and Uninstall()
methods are being mocked. A new interface K8sInstaller has been introduced to allow counterfeiter to mock the
methods.
  • Loading branch information
Nilanjan Daw authored Feb 18, 2022
1 parent 1e7592e commit d3cc0d7
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 261 deletions.
17 changes: 14 additions & 3 deletions agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"

"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/cloudinit"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/installer"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/reconciler"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/registration"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/version"
Expand Down Expand Up @@ -79,6 +80,7 @@ var (
downloadpath string
skipInstallation bool
printVersion bool
k8sInstaller reconciler.IK8sInstaller
)

// TODO - fix logging
Expand Down Expand Up @@ -149,6 +151,16 @@ func main() {
return
}

if skipInstallation {
k8sInstaller = nil
logger.Info("skip-installation flag set, skipping installer initialisation")
} else {
k8sInstaller, err = installer.New(downloadpath, logger)
if err != nil {
logger.Error(err, "failed to instantiate installer")
}
}

hostReconciler := &reconciler.HostReconciler{
Client: k8sClient,
CmdRunner: cloudinit.CmdRunner{},
Expand All @@ -158,9 +170,8 @@ func main() {
DefaultNetworkInterfaceName: registration.LocalHostRegistrar.ByoHostInfo.DefaultNetworkInterfaceName,
},
},
SkipInstallation: skipInstallation,
DownloadPath: downloadpath,
Recorder: mgr.GetEventRecorderFor("hostagent-controller"),
Recorder: mgr.GetEventRecorderFor("hostagent-controller"),
K8sInstaller: k8sInstaller,
}
if err = hostReconciler.SetupWithManager(context.TODO(), mgr); err != nil {
logger.Error(err, "unable to create controller")
Expand Down
40 changes: 18 additions & 22 deletions agent/reconciler/host_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/pkg/errors"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/cloudinit"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/installer"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/registration"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/common"
corev1 "k8s.io/api/core/v1"
Expand All @@ -28,14 +27,21 @@ import (
infrastructurev1beta1 "github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/apis/infrastructure/v1beta1"
)

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate

//counterfeiter:generate . IK8sInstaller
type IK8sInstaller interface {
Install(string, string, string) error
Uninstall(string, string, string) error
}

type HostReconciler struct {
Client client.Client
CmdRunner cloudinit.ICmdRunner
FileWriter cloudinit.IFileWriter
TemplateParser cloudinit.ITemplateParser
Recorder record.EventRecorder
SkipInstallation bool
DownloadPath string
Client client.Client
CmdRunner cloudinit.ICmdRunner
FileWriter cloudinit.IFileWriter
TemplateParser cloudinit.ITemplateParser
Recorder record.EventRecorder
K8sInstaller IK8sInstaller
}

const (
Expand Down Expand Up @@ -104,7 +110,7 @@ func (r *HostReconciler) reconcileNormal(ctx context.Context, byoHost *infrastru
return ctrl.Result{}, err
}

if r.SkipInstallation {
if r.K8sInstaller == nil {
logger.Info("Skipping installation of k8s components")
} else {
err = r.installK8sComponents(ctx, byoHost)
Expand Down Expand Up @@ -196,7 +202,7 @@ func (r *HostReconciler) hostCleanUp(ctx context.Context, byoHost *infrastructur
if err != nil {
return err
}
if r.SkipInstallation {
if r.K8sInstaller == nil {
logger.Info("Skipping uninstallation of k8s components")
} else {
err = r.uninstallk8sComponents(ctx, byoHost)
Expand Down Expand Up @@ -254,11 +260,7 @@ func (r *HostReconciler) installK8sComponents(ctx context.Context, byoHost *infr
bundleRegistry := byoHost.GetAnnotations()[infrastructurev1beta1.BundleLookupBaseRegistryAnnotation]
k8sVersion := byoHost.GetAnnotations()[infrastructurev1beta1.K8sVersionAnnotation]
byohBundleTag := byoHost.GetAnnotations()[infrastructurev1beta1.BundleLookupTagAnnotation]
bundleInstaller, err := installer.New(r.DownloadPath, logger)
if err != nil {
return err
}
err = bundleInstaller.Install(bundleRegistry, k8sVersion, byohBundleTag)
err := r.K8sInstaller.Install(bundleRegistry, k8sVersion, byohBundleTag)
if err != nil {
return err
}
Expand All @@ -269,16 +271,10 @@ func (r *HostReconciler) installK8sComponents(ctx context.Context, byoHost *infr
}

func (r *HostReconciler) uninstallk8sComponents(ctx context.Context, byoHost *infrastructurev1beta1.ByoHost) error {
logger := ctrl.LoggerFrom(ctx)

bundleRegistry := byoHost.GetAnnotations()[infrastructurev1beta1.BundleLookupBaseRegistryAnnotation]
k8sVersion := byoHost.GetAnnotations()[infrastructurev1beta1.K8sVersionAnnotation]
byohBundleTag := byoHost.GetAnnotations()[infrastructurev1beta1.BundleLookupTagAnnotation]
bundleInstaller, err := installer.New(r.DownloadPath, logger)
if err != nil {
return err
}
err = bundleInstaller.Uninstall(bundleRegistry, k8sVersion, byohBundleTag)
err := r.K8sInstaller.Uninstall(bundleRegistry, k8sVersion, byohBundleTag)
if err != nil {
return err
}
Expand Down
2 changes: 2 additions & 0 deletions agent/reconciler/reconciler_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
. "github.com/onsi/gomega"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/cloudinit/cloudinitfakes"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/reconciler"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/reconciler/reconcilerfakes"
infrastructurev1beta1 "github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/apis/infrastructure/v1beta1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -39,6 +40,7 @@ var (
fakeCommandRunner *cloudinitfakes.FakeICmdRunner
fakeFileWriter *cloudinitfakes.FakeIFileWriter
fakeTemplateParser *cloudinitfakes.FakeITemplateParser
fakeInstaller *reconcilerfakes.FakeIK8sInstaller
)

var _ = BeforeSuite(func() {
Expand Down
90 changes: 47 additions & 43 deletions agent/reconciler/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
. "github.com/onsi/gomega"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/cloudinit/cloudinitfakes"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/reconciler"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/reconciler/reconcilerfakes"
infrastructurev1beta1 "github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/apis/infrastructure/v1beta1"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/test/builder"
eventutils "github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/test/utils/events"
Expand Down Expand Up @@ -41,14 +42,15 @@ var _ = Describe("Byohost Agent Tests", func() {
fakeCommandRunner = &cloudinitfakes.FakeICmdRunner{}
fakeFileWriter = &cloudinitfakes.FakeIFileWriter{}
fakeTemplateParser = &cloudinitfakes.FakeITemplateParser{}
fakeInstaller = &reconcilerfakes.FakeIK8sInstaller{}
recorder = record.NewFakeRecorder(32)
hostReconciler = &reconciler.HostReconciler{
Client: k8sClient,
CmdRunner: fakeCommandRunner,
FileWriter: fakeFileWriter,
TemplateParser: fakeTemplateParser,
Recorder: recorder,
SkipInstallation: true,
Client: k8sClient,
CmdRunner: fakeCommandRunner,
FileWriter: fakeFileWriter,
TemplateParser: fakeTemplateParser,
Recorder: recorder,
K8sInstaller: nil,
}
})

Expand Down Expand Up @@ -175,27 +177,28 @@ runCmd:
Expect(patchHelper.Patch(ctx, byoHost, patch.WithStatusObservedGeneration{})).NotTo(HaveOccurred())
})

// It("should set K8sComponentsInstallationSucceeded to false with Reason K8sComponentsInstallationFailedReason if Install fails", func() {
// fakeInstaller.InstallReturns(errors.New("k8s components install failed"))
It("should set K8sComponentsInstallationSucceeded to false with Reason K8sComponentsInstallationFailedReason if Install fails", func() {
hostReconciler.K8sInstaller = fakeInstaller
fakeInstaller.InstallReturns(errors.New("k8s components install failed"))

// result, reconcilerErr := hostReconciler.Reconcile(ctx, controllerruntime.Request{
// NamespacedName: byoHostLookupKey,
// })
// Expect(result).To(Equal(controllerruntime.Result{}))
// Expect(reconcilerErr).To(HaveOccurred())
result, reconcilerErr := hostReconciler.Reconcile(ctx, controllerruntime.Request{
NamespacedName: byoHostLookupKey,
})
Expect(result).To(Equal(controllerruntime.Result{}))
Expect(reconcilerErr).To(HaveOccurred())

// updatedByoHost := &infrastructurev1beta1.ByoHost{}
// err := k8sClient.Get(ctx, byoHostLookupKey, updatedByoHost)
// Expect(err).ToNot(HaveOccurred())
updatedByoHost := &infrastructurev1beta1.ByoHost{}
err := k8sClient.Get(ctx, byoHostLookupKey, updatedByoHost)
Expect(err).ToNot(HaveOccurred())

// k8sComponentsInstallationSucceeded := conditions.Get(updatedByoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded)
// Expect(*k8sComponentsInstallationSucceeded).To(conditions.MatchCondition(clusterv1.Condition{
// Type: infrastructurev1beta1.K8sComponentsInstallationSucceeded,
// Status: corev1.ConditionFalse,
// Reason: infrastructurev1beta1.K8sComponentsInstallationFailedReason,
// Severity: clusterv1.ConditionSeverityInfo,
// }))
// })
k8sComponentsInstallationSucceeded := conditions.Get(updatedByoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded)
Expect(*k8sComponentsInstallationSucceeded).To(conditions.MatchCondition(clusterv1.Condition{
Type: infrastructurev1beta1.K8sComponentsInstallationSucceeded,
Status: corev1.ConditionFalse,
Reason: infrastructurev1beta1.K8sComponentsInstallationFailedReason,
Severity: clusterv1.ConditionSeverityInfo,
}))
})

It("should set K8sNodeBootstrapSucceeded to false with Reason CloudInitExecutionFailedReason if the bootstrap execution fails", func() {
fakeCommandRunner.RunCmdReturns(errors.New("I failed"))
Expand Down Expand Up @@ -428,25 +431,26 @@ runCmd:
}))
})

// It("should return error if uninstall fails", func() {
// fakeInstaller.UninstallReturns(errors.New("uninstall failed"))
// result, reconcilerErr := hostReconciler.Reconcile(ctx, controllerruntime.Request{
// NamespacedName: byoHostLookupKey,
// })
// Expect(result).To(Equal(controllerruntime.Result{}))
// Expect(reconcilerErr.Error()).To(Equal("uninstall failed"))

// updatedByoHost := &infrastructurev1beta1.ByoHost{}
// err := k8sClient.Get(ctx, byoHostLookupKey, updatedByoHost)
// Expect(err).ToNot(HaveOccurred())

// k8sNodeBootstrapSucceeded := conditions.Get(updatedByoHost, infrastructurev1beta1.K8sNodeBootstrapSucceeded)
// Expect(*k8sNodeBootstrapSucceeded).To(conditions.MatchCondition(clusterv1.Condition{
// Type: infrastructurev1beta1.K8sNodeBootstrapSucceeded,
// Status: corev1.ConditionTrue,
// }))

// })
It("should return error if uninstall fails", func() {
hostReconciler.K8sInstaller = fakeInstaller
fakeInstaller.UninstallReturns(errors.New("uninstall failed"))
result, reconcilerErr := hostReconciler.Reconcile(ctx, controllerruntime.Request{
NamespacedName: byoHostLookupKey,
})
Expect(result).To(Equal(controllerruntime.Result{}))
Expect(reconcilerErr.Error()).To(Equal("uninstall failed"))

updatedByoHost := &infrastructurev1beta1.ByoHost{}
err := k8sClient.Get(ctx, byoHostLookupKey, updatedByoHost)
Expect(err).ToNot(HaveOccurred())

k8sNodeBootstrapSucceeded := conditions.Get(updatedByoHost, infrastructurev1beta1.K8sNodeBootstrapSucceeded)
Expect(*k8sNodeBootstrapSucceeded).To(conditions.MatchCondition(clusterv1.Condition{
Type: infrastructurev1beta1.K8sNodeBootstrapSucceeded,
Status: corev1.ConditionTrue,
}))

})
})

AfterEach(func() {
Expand Down
Loading

0 comments on commit d3cc0d7

Please sign in to comment.