Skip to content

Commit

Permalink
Add unit tests for local storage (#665)
Browse files Browse the repository at this point in the history
  • Loading branch information
HomayoonAlimohammadi committed Sep 16, 2024
1 parent 72808cd commit 522a161
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 12 deletions.
8 changes: 4 additions & 4 deletions src/k8s/pkg/k8sd/features/localpv/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import (
)

var (
// chart represents manifests to deploy Rawfile LocalPV CSI.
chart = helm.InstallableChart{
// Chart represents manifests to deploy Rawfile LocalPV CSI.
Chart = helm.InstallableChart{
Name: "ck-storage",
Namespace: "kube-system",
ManifestPath: filepath.Join("charts", "rawfile-csi-0.9.0.tgz"),
}

// imageRepo is the repository to use for Rawfile LocalPV CSI.
imageRepo = "ghcr.io/canonical/rawfile-localpv"
// imageTag is the image tag to use for Rawfile LocalPV CSI.
imageTag = "0.8.0-ck4"
// ImageTag is the image tag to use for Rawfile LocalPV CSI.
ImageTag = "0.8.0-ck4"

// csiNodeDriverImage is the image to use for the CSI node driver.
csiNodeDriverImage = "ghcr.io/canonical/k8s-snap/sig-storage/csi-node-driver-registrar:v2.10.1"
Expand Down
14 changes: 7 additions & 7 deletions src/k8s/pkg/k8sd/features/localpv/localpv.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ func ApplyLocalStorage(ctx context.Context, snap snap.Snap, cfg types.LocalStora
"csiDriverArgs": []string{"--args", "rawfile", "csi-driver", "--disable-metrics"},
"image": map[string]any{
"repository": imageRepo,
"tag": imageTag,
"tag": ImageTag,
},
},
"node": map[string]any{
"image": map[string]any{
"repository": imageRepo,
"tag": imageTag,
"tag": ImageTag,
},
"storage": map[string]any{
"path": cfg.GetLocalPath(),
Expand All @@ -58,19 +58,19 @@ func ApplyLocalStorage(ctx context.Context, snap snap.Snap, cfg types.LocalStora
},
}

if _, err := m.Apply(ctx, chart, helm.StatePresentOrDeleted(cfg.GetEnabled()), values); err != nil {
if _, err := m.Apply(ctx, Chart, helm.StatePresentOrDeleted(cfg.GetEnabled()), values); err != nil {
if cfg.GetEnabled() {
err = fmt.Errorf("failed to install rawfile-csi helm package: %w", err)
return types.FeatureStatus{
Enabled: false,
Version: imageTag,
Version: ImageTag,
Message: fmt.Sprintf(deployFailedMsgTmpl, err),
}, err
} else {
err = fmt.Errorf("failed to delete rawfile-csi helm package: %w", err)
return types.FeatureStatus{
Enabled: false,
Version: imageTag,
Version: ImageTag,
Message: fmt.Sprintf(deleteFailedMsgTmpl, err),
}, err
}
Expand All @@ -79,13 +79,13 @@ func ApplyLocalStorage(ctx context.Context, snap snap.Snap, cfg types.LocalStora
if cfg.GetEnabled() {
return types.FeatureStatus{
Enabled: true,
Version: imageTag,
Version: ImageTag,
Message: fmt.Sprintf(enabledMsg, cfg.GetLocalPath()),
}, nil
} else {
return types.FeatureStatus{
Enabled: false,
Version: imageTag,
Version: ImageTag,
Message: disabledMsg,
}, nil
}
Expand Down
155 changes: 155 additions & 0 deletions src/k8s/pkg/k8sd/features/localpv/localpv_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package localpv_test

import (
"context"
"errors"
"testing"

. "github.com/onsi/gomega"
"k8s.io/utils/ptr"

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

func TestDisabled(t *testing.T) {
t.Run("HelmApplyFails", 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,
},
}
cfg := types.LocalStorage{
Enabled: ptr.To(false),
Default: ptr.To(true),
ReclaimPolicy: ptr.To("reclaim-policy"),
LocalPath: ptr.To("local-path"),
}

status, err := localpv.ApplyLocalStorage(context.Background(), snapM, cfg, nil)

g.Expect(err).To(MatchError(applyErr))
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Message).To(ContainSubstring(applyErr.Error()))
g.Expect(status.Version).To(Equal(localpv.ImageTag))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))

callArgs := helmM.ApplyCalledWith[0]
g.Expect(callArgs.Chart).To(Equal(localpv.Chart))
g.Expect(callArgs.State).To(Equal(helm.StateDeleted))

validateValues(g, callArgs.Values, cfg)
})
t.Run("Success", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
cfg := types.LocalStorage{
Enabled: ptr.To(false),
Default: ptr.To(true),
ReclaimPolicy: ptr.To("reclaim-policy"),
LocalPath: ptr.To("local-path"),
}

status, err := localpv.ApplyLocalStorage(context.Background(), snapM, cfg, nil)

g.Expect(err).ToNot(HaveOccurred())
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Version).To(Equal(localpv.ImageTag))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))

callArgs := helmM.ApplyCalledWith[0]
g.Expect(callArgs.Chart).To(Equal(localpv.Chart))
g.Expect(callArgs.State).To(Equal(helm.StateDeleted))

validateValues(g, callArgs.Values, cfg)
})
}

func TestEnabled(t *testing.T) {
t.Run("HelmApplyFails", 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,
},
}
cfg := types.LocalStorage{
Enabled: ptr.To(true),
Default: ptr.To(true),
ReclaimPolicy: ptr.To("reclaim-policy"),
LocalPath: ptr.To("local-path"),
}

status, err := localpv.ApplyLocalStorage(context.Background(), snapM, cfg, nil)

g.Expect(err).To(MatchError(applyErr))
g.Expect(status.Enabled).To(BeFalse())
g.Expect(status.Message).To(ContainSubstring(applyErr.Error()))
g.Expect(status.Version).To(Equal(localpv.ImageTag))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))

callArgs := helmM.ApplyCalledWith[0]
g.Expect(callArgs.Chart).To(Equal(localpv.Chart))
g.Expect(callArgs.State).To(Equal(helm.StatePresent))

validateValues(g, callArgs.Values, cfg)
})
t.Run("Success", func(t *testing.T) {
g := NewWithT(t)

helmM := &helmmock.Mock{}
snapM := &snapmock.Snap{
Mock: snapmock.Mock{
HelmClient: helmM,
},
}
cfg := types.LocalStorage{
Enabled: ptr.To(true),
Default: ptr.To(true),
ReclaimPolicy: ptr.To("reclaim-policy"),
LocalPath: ptr.To("local-path"),
}

status, err := localpv.ApplyLocalStorage(context.Background(), snapM, cfg, nil)

g.Expect(err).ToNot(HaveOccurred())
g.Expect(status.Enabled).To(BeTrue())
g.Expect(status.Version).To(Equal(localpv.ImageTag))
g.Expect(helmM.ApplyCalledWith).To(HaveLen(1))

callArgs := helmM.ApplyCalledWith[0]
g.Expect(callArgs.Chart).To(Equal(localpv.Chart))
g.Expect(callArgs.State).To(Equal(helm.StatePresent))

validateValues(g, callArgs.Values, cfg)
})
}

func validateValues(g Gomega, values map[string]any, cfg types.LocalStorage) {
sc := values["storageClass"].(map[string]any)
g.Expect(sc["isDefault"]).To(Equal(cfg.GetDefault()))
g.Expect(sc["reclaimPolicy"]).To(Equal(cfg.GetReclaimPolicy()))

storage := values["node"].(map[string]any)["storage"].(map[string]any)
g.Expect(storage["path"]).To(Equal(cfg.GetLocalPath()))
}
2 changes: 1 addition & 1 deletion src/k8s/pkg/k8sd/features/localpv/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func init() {
images.Register(
// Rawfile LocalPV CSI driver images
fmt.Sprintf("%s:%s", imageRepo, imageTag),
fmt.Sprintf("%s:%s", imageRepo, ImageTag),
// CSI images
csiNodeDriverImage,
csiProvisionerImage,
Expand Down

0 comments on commit 522a161

Please sign in to comment.