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

Create test to cover path of azureMachinePool.Spec.UserAssignedIdenti… #4278

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
2 changes: 1 addition & 1 deletion azure/services/identities/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type AzureClient struct {
}

// NewClient creates a new MSI client from an authorizer.
func NewClient(auth azure.Authorizer) (*AzureClient, error) {
func NewClient(auth azure.Authorizer) (Client, error) {
troy0820 marked this conversation as resolved.
Show resolved Hide resolved
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
if err != nil {
return nil, errors.Wrap(err, "failed to create identities client options")
Expand Down
4 changes: 3 additions & 1 deletion controllers/azurejson_machinepool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (r *AzureJSONMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl
// Construct secret for this machine
userAssignedIdentityIfExists := ""
if len(azureMachinePool.Spec.UserAssignedIdentities) > 0 {
idsClient, err := identities.NewClient(clusterScope)
idsClient, err := getClient(clusterScope)
if err != nil {
return reconcile.Result{}, errors.Wrap(err, "failed to create identities client")
}
Expand Down Expand Up @@ -194,3 +194,5 @@ func (r *AzureJSONMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl

return ctrl.Result{}, nil
}

var getClient = identities.NewClient
139 changes: 135 additions & 4 deletions controllers/azurejson_machinepool_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,26 @@ package controllers

import (
"context"
"os"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed to use t.Setenv

"fmt"
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/google/go-cmp/cmp"
. "github.com/onsi/gomega"
"go.uber.org/mock/gomock"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"k8s.io/utils/ptr"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
"sigs.k8s.io/cluster-api-provider-azure/azure/services/identities"
"sigs.k8s.io/cluster-api-provider-azure/azure/services/identities/mock_identities"
infrav1exp "sigs.k8s.io/cluster-api-provider-azure/exp/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/util/reconciler"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -178,9 +186,9 @@ func TestAzureJSONPoolReconciler(t *testing.T) {
},
}

os.Setenv(auth.ClientID, "fooClient")
os.Setenv(auth.ClientSecret, "fooSecret")
os.Setenv(auth.TenantID, "fooTenant")
t.Setenv(auth.ClientID, "fooClient")
t.Setenv(auth.ClientSecret, "fooSecret")
t.Setenv(auth.TenantID, "fooTenant")

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
Expand Down Expand Up @@ -210,3 +218,126 @@ func TestAzureJSONPoolReconciler(t *testing.T) {
})
}
}

func TestAzureJSONPoolReconcilerUserAssignedIdentities(t *testing.T) {
g := NewWithT(t)
ctrlr := gomock.NewController(t)
defer ctrlr.Finish()
req := ctrl.Request{NamespacedName: types.NamespacedName{Name: "fake-machine-pool", Namespace: "fake-ns"}}
ctx := context.Background()
scheme, err := newScheme()
g.Expect(err).ToNot(HaveOccurred())

azureMP := &infrav1exp.AzureMachinePool{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-machine-pool",
Namespace: "fake-ns",
Labels: map[string]string{
clusterv1.ClusterNameLabel: "fake-cluster",
},
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: fmt.Sprintf("%s/%s", expv1.GroupVersion.Group, expv1.GroupVersion.Version),
Kind: "MachinePool",
Name: "fake-other-machine-pool",
Controller: to.Ptr(true),
},
},
},
Spec: infrav1exp.AzureMachinePoolSpec{
UserAssignedIdentities: []infrav1.UserAssignedIdentity{
{
ProviderID: "fake-id",
},
},
},
}

cluster := &clusterv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-cluster",
Namespace: "fake-ns",
},
Spec: clusterv1.ClusterSpec{
InfrastructureRef: &corev1.ObjectReference{
Kind: "AzureCluster",
Name: "fake-azure-cluster",
Namespace: "fake-ns",
},
},
}

ownerMP := &expv1.MachinePool{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-other-machine-pool",
Namespace: "fake-ns",
Labels: map[string]string{
clusterv1.ClusterNameLabel: "fake-cluster",
},
},
}

azureCluster := &infrav1.AzureCluster{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use this getFakeAzureCluster function that exists here: https://github.com/willie-yao/cluster-api-provider-azure/blob/aks-fleet/controllers/azuremachine_controller_test.go#L529

However, I think there could be a case to be made to create a new file that contains all of these functions for tests, since it's a bit confusing they exist in specific controller tests but can be used across the package. I think this could be done in a follow-up PR since it'll be a bit out of scope for this issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would definitely do this but to migrate from this to that may be additional effort that may pollute the addition of this test.

Also, setting up fixtures to settle all cases where that may be useful may also pollute the repo where that may need to be tested to ensure code coverage (I know that metric isn't bound to quality, but I digress).

I can create an issue and follow up to call that out as something we would like to have.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! I think it would be good to leave as-is for the current PR

ObjectMeta: metav1.ObjectMeta{
Name: "fake-azure-cluster",
Namespace: "fake-ns",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: "cluster.x-k8s.io/v1beta1",
Kind: "Cluster",
Name: "my-cluster",
},
},
},
Spec: infrav1.AzureClusterSpec{
AzureClusterClassSpec: infrav1.AzureClusterClassSpec{
SubscriptionID: "123",
},
NetworkSpec: infrav1.NetworkSpec{
Subnets: infrav1.Subnets{
{
SubnetClassSpec: infrav1.SubnetClassSpec{
Name: "node",
Role: infrav1.SubnetNode,
},
},
},
},
},
}
apiVersion, kind := infrav1.GroupVersion.WithKind("AzureMachinePool").ToAPIVersionAndKind()

sec := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: azureMP.Name,
Namespace: "fake-ns",
Labels: map[string]string{
"fake-cluster": string(infrav1.ResourceLifecycleOwned),
},
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: apiVersion,
Kind: kind,
Name: azureMP.GetName(),
Controller: ptr.To(true),
},
},
},
}

client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(azureMP, ownerMP, cluster, azureCluster, sec).Build()
rec := AzureJSONMachinePoolReconciler{
Client: client,
Recorder: record.NewFakeRecorder(42),
ReconcileTimeout: reconciler.DefaultLoopTimeout,
}
id := "fake-id"
getClient = func(auth azure.Authorizer) (identities.Client, error) {
troy0820 marked this conversation as resolved.
Show resolved Hide resolved
mockClient := mock_identities.NewMockClient(ctrlr)
mockClient.EXPECT().GetClientID(gomock.Any(), gomock.Any()).Return(id, nil)
return mockClient, nil
}

_, err = rec.Reconcile(ctx, req)
g.Expect(err).ToNot(HaveOccurred())
}