Skip to content

Commit

Permalink
Unittests for cilium k8sd feature (#704)
Browse files Browse the repository at this point in the history
  • Loading branch information
maci3jka authored Oct 2, 2024
1 parent ed25214 commit 83ca3ed
Show file tree
Hide file tree
Showing 9 changed files with 983 additions and 136 deletions.
20 changes: 10 additions & 10 deletions src/k8s/pkg/k8sd/features/cilium/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
)

const (
gatewayDeleteFailedMsgTmpl = "Failed to delete Cilium Gateway, the error was %v"
gatewayDeployFailedMsgTmpl = "Failed to deploy Cilium Gateway, the error was %v"
GatewayDeleteFailedMsgTmpl = "Failed to delete Cilium Gateway, the error was %v"
GatewayDeployFailedMsgTmpl = "Failed to deploy Cilium Gateway, the error was %v"
)

// ApplyGateway assumes that the managed Cilium CNI is already installed on the cluster. It will fail if that is not the case.
Expand All @@ -38,7 +38,7 @@ func enableGateway(ctx context.Context, snap snap.Snap) (types.FeatureStatus, er
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeployFailedMsgTmpl, err),
}, err
}

Expand All @@ -48,7 +48,7 @@ func enableGateway(ctx context.Context, snap snap.Snap) (types.FeatureStatus, er
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeployFailedMsgTmpl, err),
}, err
}

Expand All @@ -58,7 +58,7 @@ func enableGateway(ctx context.Context, snap snap.Snap) (types.FeatureStatus, er
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeployFailedMsgTmpl, err),
}, err
}

Expand All @@ -75,7 +75,7 @@ func enableGateway(ctx context.Context, snap snap.Snap) (types.FeatureStatus, er
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeployFailedMsgTmpl, err),
}, err
}

Expand All @@ -95,7 +95,7 @@ func disableGateway(ctx context.Context, snap snap.Snap, network types.Network)
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeleteFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeleteFailedMsgTmpl, err),
}, err
}

Expand All @@ -105,7 +105,7 @@ func disableGateway(ctx context.Context, snap snap.Snap, network types.Network)
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeleteFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeleteFailedMsgTmpl, err),
}, err
}

Expand All @@ -116,7 +116,7 @@ func disableGateway(ctx context.Context, snap snap.Snap, network types.Network)
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeleteFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeleteFailedMsgTmpl, err),
}, err
}

Expand All @@ -133,7 +133,7 @@ func disableGateway(ctx context.Context, snap snap.Snap, network types.Network)
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(gatewayDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(GatewayDeployFailedMsgTmpl, err),
}, err
}

Expand Down
273 changes: 273 additions & 0 deletions src/k8s/pkg/k8sd/features/cilium/gateway_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
package cilium_test

import (
"context"
"errors"
"fmt"
"testing"

"github.com/canonical/k8s/pkg/client/helm"
helmmock "github.com/canonical/k8s/pkg/client/helm/mock"
"github.com/canonical/k8s/pkg/client/kubernetes"
"github.com/canonical/k8s/pkg/k8sd/features/cilium"
"github.com/canonical/k8s/pkg/k8sd/types"
snapmock "github.com/canonical/k8s/pkg/snap/mock"

. "github.com/onsi/gomega"
v1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/utils/ptr"
)

func TestGatewayEnabled(t *testing.T) {
t.Run("HelmApplyErr", func(t *testing.T) {
g := NewWithT(t)

applyErr := errors.New("failed to apply")
helmM := &helmmock.Mock{
ApplyErr: applyErr,
}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(true),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).To(HaveOccurred())
g.Expect(err).To(MatchError(applyErr))
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(fmt.Sprintf(cilium.GatewayDeployFailedMsgTmpl, err)))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))
})

t.Run("AlreadyDeployed", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: false,
}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(true),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).NotTo(HaveOccurred())
g.Expect(status.Enabled).To(BeTrue())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(cilium.EnabledMsg))

helmCiliumArgs := helmM.ApplyCalledWith[2]
g.Expect(helmCiliumArgs.Chart).To(Equal(cilium.ChartCilium))
g.Expect(helmCiliumArgs.State).To(Equal(helm.StateUpgradeOnly))
g.Expect(helmCiliumArgs.Values["gatewayAPI"].(map[string]any)["enabled"]).To(Equal(true))
})

t.Run("RolloutFail", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: true,
}
clientset := fake.NewSimpleClientset()
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
KubernetesClient: &kubernetes.Client{
Interface: clientset,
},
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(true),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).To(HaveOccurred())
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(fmt.Sprintf(cilium.GatewayDeployFailedMsgTmpl, err)))
})

t.Run("Success", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: true,
}
clientset := fake.NewSimpleClientset(
&v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "cilium-operator",
Namespace: "kube-system",
},
},
&v1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "cilium",
Namespace: "kube-system",
},
},
)
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
KubernetesClient: &kubernetes.Client{
Interface: clientset,
},
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(true),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).NotTo(HaveOccurred())
g.Expect(status.Enabled).To(BeTrue())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(cilium.EnabledMsg))
})

}

func TestGatewayDisabled(t *testing.T) {
t.Run("HelmApplyErr", func(t *testing.T) {
g := NewWithT(t)

applyErr := errors.New("failed to apply")
helmM := &helmmock.Mock{
ApplyErr: applyErr,
}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(false),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).To(HaveOccurred())
g.Expect(err).To(MatchError(applyErr))
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(fmt.Sprintf(cilium.GatewayDeleteFailedMsgTmpl, err)))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))
})

t.Run("AlreadyDeleted", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: false,
}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(false),
}
status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(cilium.DisabledMsg))

helmCiliumArgs := helmM.ApplyCalledWith[1]
g.Expect(helmCiliumArgs.Chart).To(Equal(cilium.ChartCilium))
g.Expect(helmCiliumArgs.State).To(Equal(helm.StateDeleted))
g.Expect(helmCiliumArgs.Values["gatewayAPI"].(map[string]any)["enabled"]).To(Equal(false))

})

t.Run("RolloutFail", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: true,
}
clientset := fake.NewSimpleClientset()
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
KubernetesClient: &kubernetes.Client{
Interface: clientset,
},
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(false),
}
status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)
g.Expect(err).To(HaveOccurred())
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(fmt.Sprintf(cilium.GatewayDeployFailedMsgTmpl, err)))
})

t.Run("Success", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{
ApplyChanged: true,
}
clientset := fake.NewSimpleClientset(
&v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "cilium-operator",
Namespace: "kube-system",
},
},
&v1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "cilium",
Namespace: "kube-system",
},
},
)
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
KubernetesClient: &kubernetes.Client{
Interface: clientset,
},
},
}
network := types.Network{}
gateway := types.Gateway{
Enabled: ptr.To(false),
}

status, err := cilium.ApplyGateway(context.Background(), snapM, gateway, network, nil)

g.Expect(err).NotTo(HaveOccurred())
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(cilium.CiliumAgentImageTag))
g.Expect(status.Message).To(Equal(cilium.DisabledMsg))
})
}
10 changes: 5 additions & 5 deletions src/k8s/pkg/k8sd/features/cilium/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
)

const (
ingressDeleteFailedMsgTmpl = "Failed to delete Cilium Ingress, the error was: %v"
ingressDeployFailedMsgTmpl = "Failed to deploy Cilium Ingress, the error was: %v"
IngressDeleteFailedMsgTmpl = "Failed to delete Cilium Ingress, the error was: %v"
IngressDeployFailedMsgTmpl = "Failed to deploy Cilium Ingress, the error was: %v"
)

// ApplyIngress assumes that the managed Cilium CNI is already installed on the cluster. It will fail if that is not the case.
Expand Down Expand Up @@ -54,14 +54,14 @@ func ApplyIngress(ctx context.Context, snap snap.Snap, ingress types.Ingress, ne
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(ingressDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(IngressDeployFailedMsgTmpl, err),
}, err
} else {
err = fmt.Errorf("failed to disable ingress: %w", err)
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(ingressDeleteFailedMsgTmpl, err),
Message: fmt.Sprintf(IngressDeleteFailedMsgTmpl, err),
}, err
}
}
Expand Down Expand Up @@ -95,7 +95,7 @@ func ApplyIngress(ctx context.Context, snap snap.Snap, ingress types.Ingress, ne
return types.FeatureStatus{
Enabled: false,
Version: CiliumAgentImageTag,
Message: fmt.Sprintf(ingressDeployFailedMsgTmpl, err),
Message: fmt.Sprintf(IngressDeployFailedMsgTmpl, err),
}, err
}

Expand Down
Loading

0 comments on commit 83ca3ed

Please sign in to comment.