diff --git a/.golangci.yaml b/.golangci.yaml index 4655fb04..bead1a9b 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -7,6 +7,7 @@ issues: - "should not use dot imports" - "don't use an underscore in package name" - "exported: .*" + - "could not import" linters-settings: gci: diff --git a/images/agent/src/go.mod b/images/agent/src/go.mod index 92ca11e2..d0a1ece8 100644 --- a/images/agent/src/go.mod +++ b/images/agent/src/go.mod @@ -3,7 +3,7 @@ module agent go 1.22.2 require ( - github.com/deckhouse/sds-node-configurator/api v0.0.0-20240709091744-c9d24f05db41 + github.com/deckhouse/sds-node-configurator/api v0.0.0-20240805103635-969dc811217b github.com/go-logr/logr v1.4.1 github.com/google/go-cmp v0.6.0 github.com/onsi/ginkgo/v2 v2.17.1 diff --git a/images/agent/src/go.sum b/images/agent/src/go.sum index ce706c7a..623d8d8a 100644 --- a/images/agent/src/go.sum +++ b/images/agent/src/go.sum @@ -9,8 +9,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckhouse/sds-node-configurator/api v0.0.0-20240709091744-c9d24f05db41 h1:kfnAfII4E8yWkDZ4FJIPO9/OvXkMIQDPLB3zzNBo8Wg= -github.com/deckhouse/sds-node-configurator/api v0.0.0-20240709091744-c9d24f05db41/go.mod h1:H71+9G0Jr46Qs0BA3z3/xt0h9lbnJnCEYcaCJCWFBf0= +github.com/deckhouse/sds-node-configurator/api v0.0.0-20240805103635-969dc811217b h1:EYmHWTWcWMpyxJGZK05ZxlIFnh9s66DRrxLw/LNb/xw= +github.com/deckhouse/sds-node-configurator/api v0.0.0-20240805103635-969dc811217b/go.mod h1:H71+9G0Jr46Qs0BA3z3/xt0h9lbnJnCEYcaCJCWFBf0= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= diff --git a/images/agent/src/pkg/controller/block_device_test.go b/images/agent/src/pkg/controller/block_device_test.go index 17d5c377..2e85c470 100644 --- a/images/agent/src/pkg/controller/block_device_test.go +++ b/images/agent/src/pkg/controller/block_device_test.go @@ -17,11 +17,18 @@ limitations under the License. package controller import ( + "agent/config" "agent/internal" + "agent/pkg/cache" "agent/pkg/logger" + "agent/pkg/monitoring" "agent/pkg/utils" + "bytes" "fmt" "github.com/deckhouse/sds-node-configurator/api/v1alpha1" + errors2 "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" "testing" "k8s.io/apimachinery/pkg/api/resource" @@ -30,6 +37,186 @@ import ( ) func TestBlockDeviceCtrl(t *testing.T) { + log, _ := logger.NewLogger("1") + cfg := config.Options{ + NodeName: "test-node", + MachineId: "test-id", + } + + t.Run("shouldDeleteBlockDevice", func(t *testing.T) { + t.Run("returns_true", func(t *testing.T) { + bd := v1alpha1.BlockDevice{ + Status: v1alpha1.BlockDeviceStatus{ + NodeName: cfg.NodeName, + Consumable: true, + }, + } + actual := map[string]struct{}{} + + assert.True(t, shouldDeleteBlockDevice(bd, actual, cfg.NodeName)) + }) + + t.Run("returns_false_cause_of_dif_node", func(t *testing.T) { + bd := v1alpha1.BlockDevice{ + Status: v1alpha1.BlockDeviceStatus{ + NodeName: cfg.NodeName, + Consumable: true, + }, + } + actual := map[string]struct{}{} + + assert.False(t, shouldDeleteBlockDevice(bd, actual, "dif-node")) + }) + + t.Run("returns_false_cause_of_not_consumable", func(t *testing.T) { + bd := v1alpha1.BlockDevice{ + Status: v1alpha1.BlockDeviceStatus{ + NodeName: cfg.NodeName, + Consumable: false, + }, + } + actual := map[string]struct{}{} + + assert.False(t, shouldDeleteBlockDevice(bd, actual, cfg.NodeName)) + }) + + t.Run("returns_false_cause_of_not_deprecated", func(t *testing.T) { + const name = "test" + bd := v1alpha1.BlockDevice{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: cfg.NodeName, + Consumable: true, + }, + } + actual := map[string]struct{}{ + name: {}, + } + + assert.False(t, shouldDeleteBlockDevice(bd, actual, cfg.NodeName)) + }) + }) + + t.Run("RemoveDeprecatedAPIDevices", func(t *testing.T) { + const ( + goodName = "test-candidate1" + badName = "test-candidate2" + ) + cl := NewFakeClient() + candidates := []internal.BlockDeviceCandidate{ + { + NodeName: cfg.NodeName, + Consumable: false, + PVUuid: "142412421", + VGUuid: "123123123", + LvmVolumeGroupName: "test-lvg", + ActualVGNameOnTheNode: "test-vg", + Wwn: "12414212", + Serial: "1412412412412", + Path: "/dev/vdb", + Size: resource.MustParse("1G"), + Rota: false, + Model: "124124-adf", + Name: goodName, + HotPlug: false, + MachineId: "1245151241241", + }, + } + + bds := map[string]v1alpha1.BlockDevice{ + goodName: { + ObjectMeta: metav1.ObjectMeta{ + Name: goodName, + }, + }, + badName: { + ObjectMeta: metav1.ObjectMeta{ + Name: badName, + }, + Status: v1alpha1.BlockDeviceStatus{ + Consumable: true, + NodeName: cfg.NodeName, + }, + }, + } + + for _, bd := range bds { + err := cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + defer func() { + for _, bd := range bds { + cl.Delete(ctx, &bd) + } + }() + + for _, bd := range bds { + createdBd := &v1alpha1.BlockDevice{} + err := cl.Get(ctx, client.ObjectKey{ + Name: bd.Name, + }, createdBd) + if err != nil { + t.Error(err) + } + assert.Equal(t, bd.Name, createdBd.Name) + } + + RemoveDeprecatedAPIDevices(ctx, cl, *log, monitoring.GetMetrics(cfg.NodeName), candidates, bds, cfg.NodeName) + + _, ok := bds[badName] + assert.False(t, ok) + + deleted := &v1alpha1.BlockDevice{} + err := cl.Get(ctx, client.ObjectKey{ + Name: badName, + }, deleted) + if assert.True(t, errors2.IsNotFound(err)) { + assert.Equal(t, "", deleted.Name) + } + }) + + t.Run("GetBlockDeviceCandidates", func(t *testing.T) { + devices := []internal.Device{ + { + Name: "valid1", + Size: resource.MustParse("1G"), + Serial: "131412", + }, + { + Name: "valid2", + Size: resource.MustParse("1G"), + Serial: "12412412", + }, + { + Name: "valid3", + Size: resource.MustParse("1G"), + Serial: "4214215", + }, + { + Name: "invalid", + FSType: "ext4", + Size: resource.MustParse("1G"), + }, + } + + sdsCache := cache.New() + sdsCache.StoreDevices(devices, bytes.Buffer{}) + + candidates := GetBlockDeviceCandidates(*log, cfg, sdsCache) + + assert.Equal(t, 3, len(candidates)) + for i := range candidates { + assert.Equal(t, devices[i].Name, candidates[i].Path) + assert.Equal(t, cfg.MachineId, candidates[i].MachineId) + assert.Equal(t, cfg.NodeName, candidates[i].NodeName) + } + }) + t.Run("CheckConsumable", func(t *testing.T) { t.Run("Good device returns true", func(t *testing.T) { goodDevice := internal.Device{ @@ -205,10 +392,6 @@ func TestBlockDeviceCtrl(t *testing.T) { }) t.Run("validateTestLSBLKOutput", func(t *testing.T) { - log, err := logger.NewLogger("1") - if err != nil { - t.Fatal(err) - } testLsblkOutputBytes := []byte(testLsblkOutput) devices, err := utils.UnmarshalDevices(testLsblkOutputBytes) if assert.NoError(t, err) { diff --git a/images/agent/src/pkg/controller/controller_reconcile_test.go b/images/agent/src/pkg/controller/controller_reconcile_test.go index 91929698..cad019d2 100644 --- a/images/agent/src/pkg/controller/controller_reconcile_test.go +++ b/images/agent/src/pkg/controller/controller_reconcile_test.go @@ -21,8 +21,9 @@ import ( "agent/pkg/controller" "agent/pkg/monitoring" "context" - + "github.com/deckhouse/sds-node-configurator/api/v1alpha1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -138,7 +139,11 @@ var _ = Describe("Storage Controller", func() { }) It("DeleteAPIBlockDevice", func() { - err := controller.DeleteAPIBlockDevice(ctx, cl, testMetrics, deviceName) + err := controller.DeleteAPIBlockDevice(ctx, cl, testMetrics, &v1alpha1.BlockDevice{ + ObjectMeta: metav1.ObjectMeta{ + Name: deviceName, + }, + }) Expect(err).NotTo(HaveOccurred()) devices, err := controller.GetAPIBlockDevices(context.Background(), cl, testMetrics) diff --git a/images/agent/src/pkg/controller/lvm_logical_volume_bench_test.go b/images/agent/src/pkg/controller/lvm_logical_volume_bench_test.go index 2aff0247..eb53e209 100644 --- a/images/agent/src/pkg/controller/lvm_logical_volume_bench_test.go +++ b/images/agent/src/pkg/controller/lvm_logical_volume_bench_test.go @@ -20,10 +20,10 @@ import ( ) var ( - lvgName = "hdd-lvg-on-node-0" - poolName = "hhd-thin" - lvCount = 600 - size, err = resource.ParseQuantity("1Gi") + lvgName = "hdd-lvg-on-node-0" + poolName = "hhd-thin" + lvCount = 600 + size = "1Gi" resizeOn = false @@ -85,7 +85,9 @@ func BenchmarkRunThickLLVCreationSingleThread(b *testing.B) { continue } - llv.Spec.Size.Add(add) + lvsize := resource.MustParse(llv.Spec.Size) + lvsize.Add(add) + llv.Spec.Size = lvsize.String() err = e2eCL.Update(ctx, &llv) if err != nil { b.Logf(err.Error()) @@ -150,7 +152,9 @@ func BenchmarkRunThinLLVCreationSingleThread(b *testing.B) { continue } - llv.Spec.Size.Add(add) + lvsize := resource.MustParse(llv.Spec.Size) + lvsize.Add(add) + llv.Spec.Size = lvsize.String() err = e2eCL.Update(ctx, &llv) if err != nil { b.Logf(err.Error()) diff --git a/images/agent/src/pkg/controller/lvm_logical_volume_watcher_func.go b/images/agent/src/pkg/controller/lvm_logical_volume_watcher_func.go index 78a474e9..69ad055f 100644 --- a/images/agent/src/pkg/controller/lvm_logical_volume_watcher_func.go +++ b/images/agent/src/pkg/controller/lvm_logical_volume_watcher_func.go @@ -98,9 +98,9 @@ func removeLLVFinalizersIfExist( if removed { log.Trace(fmt.Sprintf("[removeLLVFinalizersIfExist] removed finalizer %s from the LVMLogicalVolume %s", internal.SdsNodeConfiguratorFinalizer, llv.Name)) - err := updateLVMLogicalVolume(ctx, metrics, cl, llv) + err := updateLVMLogicalVolumeSpec(ctx, metrics, cl, llv) if err != nil { - log.Error(err, fmt.Sprintf("[updateLVMLogicalVolume] unable to update the LVMVolumeGroup %s", llv.Name)) + log.Error(err, fmt.Sprintf("[updateLVMLogicalVolumeSpec] unable to update the LVMVolumeGroup %s", llv.Name)) return err } } @@ -194,7 +194,7 @@ func addLLVFinalizerIfNotExist(ctx context.Context, cl client.Client, log logger llv.Finalizers = append(llv.Finalizers, internal.SdsNodeConfiguratorFinalizer) log.Trace(fmt.Sprintf("[addLLVFinalizerIfNotExist] added finalizer %s to the LVMLogicalVolume %s", internal.SdsNodeConfiguratorFinalizer, llv.Name)) - err := updateLVMLogicalVolume(ctx, metrics, cl, llv) + err := updateLVMLogicalVolumeSpec(ctx, metrics, cl, llv) if err != nil { return false, err } @@ -300,13 +300,13 @@ func validateLVMLogicalVolume(sdsCache *cache.Cache, llv *v1alpha1.LVMLogicalVol // if a specified Thick LV name matches the existing Thin one lv := sdsCache.FindLV(lvg.Spec.ActualVGNameOnTheNode, llv.Spec.ActualLVNameOnTheNode) - if lv != nil && len(lv.LVAttr) == 0 { - reason.WriteString(fmt.Sprintf("LV %s was found on the node, but can't be validated due to its attributes is empty string. ", lv.LVName)) - } - if lv != nil { - if !checkIfLVBelongsToLLV(llv, lv) { - reason.WriteString(fmt.Sprintf("Specified LV %s is already created and it is doesnt match the one on the node.", lv.LVName)) + if len(lv.LVAttr) == 0 { + reason.WriteString(fmt.Sprintf("LV %s was found on the node, but can't be validated due to its attributes is empty string. ", lv.LVName)) + } else { + if !checkIfLVBelongsToLLV(llv, lv) { + reason.WriteString(fmt.Sprintf("Specified LV %s is already created and it is doesnt match the one on the node.", lv.LVName)) + } } } @@ -342,7 +342,7 @@ func updateLVMLogicalVolumePhaseIfNeeded(ctx context.Context, cl client.Client, return nil } -func updateLVMLogicalVolume(ctx context.Context, metrics monitoring.Metrics, cl client.Client, llv *v1alpha1.LVMLogicalVolume) error { +func updateLVMLogicalVolumeSpec(ctx context.Context, metrics monitoring.Metrics, cl client.Client, llv *v1alpha1.LVMLogicalVolume) error { return cl.Update(ctx, llv) } diff --git a/images/agent/src/pkg/controller/lvm_logical_volume_watcher_test.go b/images/agent/src/pkg/controller/lvm_logical_volume_watcher_test.go index ba81dd61..395a8db2 100644 --- a/images/agent/src/pkg/controller/lvm_logical_volume_watcher_test.go +++ b/images/agent/src/pkg/controller/lvm_logical_volume_watcher_test.go @@ -7,7 +7,6 @@ import ( "agent/pkg/monitoring" "agent/pkg/utils" "bytes" - "fmt" "github.com/deckhouse/sds-node-configurator/api/v1alpha1" "testing" @@ -23,7 +22,6 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { log = logger.Logger{} metrics = monitoring.Metrics{} vgName = "test-vg" - delta = resource.MustParse(internal.ResizeDelta) ) t.Run("subtractQuantity_returns_correct_value", func(t *testing.T) { @@ -119,12 +117,12 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Spec: v1alpha1.LVMLogicalVolumeSpec{ ActualLVNameOnTheNode: "test-lv", Type: Thick, - Size: resource.MustParse("10M"), + Size: "10M", LvmVolumeGroupName: lvgName, }, } - v, r := validateLVMLogicalVolume(&cache.Cache{}, llv, lvg, delta) + v, r := validateLVMLogicalVolume(&cache.Cache{}, llv, lvg) if assert.True(t, v) { assert.Equal(t, 0, len(r)) } @@ -137,7 +135,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Spec: v1alpha1.LVMLogicalVolumeSpec{ ActualLVNameOnTheNode: lvName, Type: Thick, - Size: resource.MustParse("0M"), + Size: "0M", LvmVolumeGroupName: "some-lvg", Thin: &v1alpha1.LVMLogicalVolumeThinSpec{PoolName: "some-lvg"}, }, @@ -150,9 +148,9 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { }, }, bytes.Buffer{}) - v, r := validateLVMLogicalVolume(sdsCache, llv, &v1alpha1.LvmVolumeGroup{}, delta) + v, r := validateLVMLogicalVolume(sdsCache, llv, &v1alpha1.LvmVolumeGroup{}) if assert.False(t, v) { - assert.Equal(t, "zero size for LV; no LV name specified; thin pool specified for Thick LV; ", r) + assert.Equal(t, "Zero size for LV. Thin pool specified for Thick LV. LV test-lv was found on the node, but can't be validated due to its attributes is empty string. ", r) } }) @@ -169,7 +167,8 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Status: v1alpha1.LvmVolumeGroupStatus{ ThinPools: []v1alpha1.LvmVolumeGroupThinPoolStatus{ { - Name: tpName, + Name: tpName, + AllocationLimit: internal.AllocationLimitDefaultValue, }, }, }, @@ -179,25 +178,24 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Spec: v1alpha1.LVMLogicalVolumeSpec{ ActualLVNameOnTheNode: "test-lv", Type: Thin, - Size: resource.MustParse("10M"), + Size: "10M", LvmVolumeGroupName: lvgName, Thin: &v1alpha1.LVMLogicalVolumeThinSpec{PoolName: tpName}, }, } - v, r := validateLVMLogicalVolume(cache.New(), llv, lvg, delta) + v, r := validateLVMLogicalVolume(cache.New(), llv, lvg) if assert.True(t, v) { assert.Equal(t, 0, len(r)) } }) t.Run("thin_all_bad_returns_false", func(t *testing.T) { - llv := &v1alpha1.LVMLogicalVolume{ Spec: v1alpha1.LVMLogicalVolumeSpec{ ActualLVNameOnTheNode: "", Type: Thin, - Size: resource.MustParse("0M"), + Size: "0M", LvmVolumeGroupName: "some-lvg", }, } @@ -209,9 +207,9 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { }, }, bytes.Buffer{}) - v, r := validateLVMLogicalVolume(sdsCache, llv, &v1alpha1.LvmVolumeGroup{}, delta) + v, r := validateLVMLogicalVolume(sdsCache, llv, &v1alpha1.LvmVolumeGroup{}) if assert.False(t, v) { - assert.Equal(t, "zero size for LV; no LV name specified; no thin pool specified; ", r) + assert.Equal(t, "No LV name specified. Zero size for LV. No thin pool specified. ", r) } }) @@ -224,10 +222,10 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualSize: resource.MustParse("10Gi"), UsedSize: resource.MustParse("1Gi"), AllocatedSize: resource.MustParse("5Gi"), - AllocationLimit: "150%", + AllocationLimit: internal.AllocationLimitDefaultValue, } - free, err := getThinPoolAvailableSpace(tp.ActualSize, tp.AllocatedSize, tpName) + free, err := getThinPoolAvailableSpace(tp.ActualSize, tp.AllocatedSize, tp.AllocationLimit) if err != nil { t.Error(err) } @@ -271,23 +269,20 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { }) t.Run("returns_update", func(t *testing.T) { - specSize := resource.NewQuantity(40000000000, resource.BinarySI) - statusSize := resource.NewQuantity(10000000000, resource.BinarySI) lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ Spec: v1alpha1.LVMLogicalVolumeSpec{ ActualLVNameOnTheNode: lvName, - Size: *specSize, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseCreated, - ActualSize: *statusSize, + Phase: LLVStatusPhaseCreated, }, } sdsCache := cache.New() sdsCache.StoreLVs([]internal.LVData{ { LVName: lvName, + VGName: vgName, }, }, bytes.Buffer{}) @@ -308,63 +303,66 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { assert.Equal(t, DeleteReconcile, actual) }) + }) - t.Run("returns_empty", func(t *testing.T) { - specSize := resource.NewQuantity(40000000000, resource.BinarySI) - statusSize := resource.NewQuantity(40000000000, resource.BinarySI) + t.Run("shouldReconcileByCreateFunc", func(t *testing.T) { + t.Run("if_lv_is_not_created_returns_true", func(t *testing.T) { + lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ Spec: v1alpha1.LVMLogicalVolumeSpec{ - Size: *specSize, + ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseCreated, - ActualSize: *statusSize, + Phase: LLVStatusPhaseCreated, }, } - actual := identifyReconcileFunc(cache.New(), vgName, llv) - - assert.Equal(t, reconcileType(""), actual) - }) - }) - - t.Run("shouldReconcileByCreateFunc", func(t *testing.T) { - t.Run("if_status_nill_returns_true", func(t *testing.T) { - llv := &v1alpha1.LVMLogicalVolume{} - should := shouldReconcileByCreateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.True(t, should) - } + assert.True(t, should) }) - t.Run("if_phase_created_returns_false", func(t *testing.T) { + t.Run("if_lv_is_created_returns_false", func(t *testing.T) { + lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ + Spec: v1alpha1.LVMLogicalVolumeSpec{ + ActualLVNameOnTheNode: lvName, + }, Status: &v1alpha1.LVMLogicalVolumeStatus{ Phase: LLVStatusPhaseCreated, }, } - - should := shouldReconcileByCreateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } + sdsCache := cache.New() + sdsCache.StoreLVs([]internal.LVData{ + { + LVName: lvName, + VGName: vgName, + }, + }, bytes.Buffer{}) + should := shouldReconcileByCreateFunc(sdsCache, vgName, llv) + assert.False(t, should) }) - t.Run("if_phase_resizing_returns_false", func(t *testing.T) { + t.Run("if_deletion_timestamp_is_not_nil_returns_false", func(t *testing.T) { + lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ + ObjectMeta: v1.ObjectMeta{DeletionTimestamp: &v1.Time{}}, + Spec: v1alpha1.LVMLogicalVolumeSpec{ + ActualLVNameOnTheNode: lvName, + }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseResizing, + Phase: LLVStatusPhaseCreated, }, } + sdsCache := cache.New() + sdsCache.StoreLVs([]internal.LVData{ + { + LVName: lvName, + VGName: vgName, + }, + }, bytes.Buffer{}) should := shouldReconcileByCreateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } + assert.False(t, should) }) }) @@ -377,108 +375,42 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { } should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } - }) - - t.Run("if_status_nil_returns_false", func(t *testing.T) { - llv := &v1alpha1.LVMLogicalVolume{} - - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } - }) - - t.Run("if_phase_pending_returns_false", func(t *testing.T) { - llv := &v1alpha1.LVMLogicalVolume{ - Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhasePending, - }, - } - - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } - }) - - t.Run("if_phase_resizing_returns_false", func(t *testing.T) { - llv := &v1alpha1.LVMLogicalVolume{ - Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseResizing, - }, - } - - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } + assert.False(t, should) }) - t.Run("if_spec_size_less_than_status_one_returns_false_and_error", func(t *testing.T) { - specSize := resource.NewQuantity(100000000, resource.BinarySI) - statusSize := resource.NewQuantity(200000000, resource.BinarySI) + t.Run("if_lv_exists_returns_true", func(t *testing.T) { + lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ Spec: v1alpha1.LVMLogicalVolumeSpec{ - Size: *specSize, + ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseCreated, - ActualSize: *statusSize, + Phase: LLVStatusPhaseCreated, }, } - - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.ErrorContains(t, err, fmt.Sprintf("requested size %d is less than actual %d", llv.Spec.Size.Value(), llv.Status.ActualSize.Value())) { - assert.False(t, should) - } - }) - - t.Run("if_spec_size_more_than_status_one_but_less_than_delta_returns_false", func(t *testing.T) { - specSize := resource.NewQuantity(30000, resource.BinarySI) - statusSize := resource.NewQuantity(20000, resource.BinarySI) - llv := &v1alpha1.LVMLogicalVolume{ - Spec: v1alpha1.LVMLogicalVolumeSpec{ - Size: *specSize, - }, - Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseCreated, - ActualSize: *statusSize, + sdsCache := cache.New() + sdsCache.StoreLVs([]internal.LVData{ + { + LVName: lvName, + VGName: vgName, }, - } - - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.False(t, should) - } + }, bytes.Buffer{}) + should := shouldReconcileByUpdateFunc(sdsCache, vgName, llv) + assert.True(t, should) }) - t.Run("if_spec_size_more_than_status_returns_true", func(t *testing.T) { - specSize := resource.NewQuantity(40000000000, resource.BinarySI) - statusSize := resource.NewQuantity(10000000000, resource.BinarySI) + t.Run("if_lv_does_not_exist_returns_false", func(t *testing.T) { + lvName := "test-lv" llv := &v1alpha1.LVMLogicalVolume{ Spec: v1alpha1.LVMLogicalVolumeSpec{ - Size: *specSize, + ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: LLVStatusPhaseCreated, - ActualSize: *statusSize, + Phase: LLVStatusPhaseCreated, }, } - should := shouldReconcileByUpdateFunc(cache.New(), vgName, llv) - - if assert.NoError(t, err) { - assert.True(t, should) - } + assert.False(t, should) }) }) @@ -618,20 +550,27 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { }) }) - t.Run("updateLVMLogicalVolume", func(t *testing.T) { + t.Run("updateLVMLogicalVolumeSpec", func(t *testing.T) { const ( lvgName = "test-lvg" - oldSize = int64(100000000) - newSize = int64(200000000) + ) + var ( + oldSize = resource.NewQuantity(100000000, resource.BinarySI) + newSize = resource.NewQuantity(200000000, resource.BinarySI) ) llv := &v1alpha1.LVMLogicalVolume{ ObjectMeta: v1.ObjectMeta{ Name: lvgName, }, + Spec: v1alpha1.LVMLogicalVolumeSpec{ + ActualLVNameOnTheNode: "", + Type: "", + Size: oldSize.String(), + }, Status: &v1alpha1.LVMLogicalVolumeStatus{ Phase: LLVStatusPhasePending, Reason: "", - ActualSize: *resource.NewQuantity(oldSize, resource.BinarySI), + ActualSize: *oldSize, }, } @@ -659,13 +598,14 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { if assert.NotNil(t, oldLLV) { assert.Equal(t, LLVStatusPhasePending, oldLLV.Status.Phase) - assert.Equal(t, oldSize, oldLLV.Status.ActualSize.Value()) + assert.Equal(t, oldSize.Value(), oldLLV.Status.ActualSize.Value()) } + oldLLV.Spec.Size = newSize.String() oldLLV.Status.Phase = LLVStatusPhaseCreated - oldLLV.Status.ActualSize = *resource.NewQuantity(newSize, resource.BinarySI) - err = updateLVMLogicalVolume(ctx, metrics, cl, oldLLV) + oldLLV.Status.ActualSize = *newSize + err = updateLVMLogicalVolumeSpec(ctx, metrics, cl, oldLLV) if assert.NoError(t, err) { newLLV := &v1alpha1.LVMLogicalVolume{} err = cl.Get(ctx, client.ObjectKey{ @@ -676,8 +616,79 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { return } + assert.Equal(t, LLVStatusPhasePending, newLLV.Status.Phase) + assert.Equal(t, oldSize.Value(), newLLV.Status.ActualSize.Value()) + } + }) + + t.Run("updateLLVPhaseToCreatedIfNeeded", func(t *testing.T) { + const ( + lvgName = "test-lvg" + ) + var ( + oldSize = resource.NewQuantity(100000000, resource.BinarySI) + newSize = resource.NewQuantity(200000000, resource.BinarySI) + ) + llv := &v1alpha1.LVMLogicalVolume{ + ObjectMeta: v1.ObjectMeta{ + Name: lvgName, + }, + Spec: v1alpha1.LVMLogicalVolumeSpec{ + ActualLVNameOnTheNode: "", + Type: "", + Size: oldSize.String(), + }, + Status: &v1alpha1.LVMLogicalVolumeStatus{ + Phase: LLVStatusPhasePending, + Reason: "", + ActualSize: *oldSize, + }, + } + + err := cl.Create(ctx, llv) + if err != nil { + t.Error(err) + return + } + + defer func() { + err = cl.Delete(ctx, llv) + if err != nil { + t.Error(err) + } + }() + + oldLLV := &v1alpha1.LVMLogicalVolume{} + err = cl.Get(ctx, client.ObjectKey{ + Name: llv.Name, + }, oldLLV) + if err != nil { + t.Error(err) + return + } + + if assert.NotNil(t, oldLLV) { + assert.Equal(t, LLVStatusPhasePending, oldLLV.Status.Phase) + assert.Equal(t, oldSize.Value(), oldLLV.Status.ActualSize.Value()) + } + + oldLLV.Spec.Size = newSize.String() + + updated, err := updateLLVPhaseToCreatedIfNeeded(ctx, cl, oldLLV, *newSize) + if assert.NoError(t, err) { + assert.True(t, updated) + newLLV := &v1alpha1.LVMLogicalVolume{} + err = cl.Get(ctx, client.ObjectKey{ + Name: llv.Name, + }, newLLV) + if err != nil { + t.Error(err) + return + } + + assert.Equal(t, oldSize.String(), newLLV.Spec.Size) assert.Equal(t, LLVStatusPhaseCreated, newLLV.Status.Phase) - assert.Equal(t, newSize, newLLV.Status.ActualSize.Value()) + assert.Equal(t, newSize.Value(), newLLV.Status.ActualSize.Value()) } }) @@ -730,33 +741,24 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { t.Run("AreSizesEqualWithinDelta", func(t *testing.T) { t.Run("returns_true", func(t *testing.T) { size := 10000000000 - delta, err := resource.ParseQuantity(internal.ResizeDelta) - if err != nil { - t.Error(err) - } left := resource.NewQuantity(int64(size), resource.BinarySI) - right := resource.NewQuantity(int64(size)+delta.Value()-1, resource.BinarySI) + right := resource.NewQuantity(int64(size)+internal.ResizeDelta.Value()-1, resource.BinarySI) - equal := utils.AreSizesEqualWithinDelta(*left, *right, delta) + equal := utils.AreSizesEqualWithinDelta(*left, *right, internal.ResizeDelta) assert.True(t, equal) }) t.Run("returns_false", func(t *testing.T) { size := 10000000000 - delta, err := resource.ParseQuantity(internal.ResizeDelta) - if err != nil { - t.Error(err) - } left := resource.NewQuantity(int64(size), resource.BinarySI) - right := resource.NewQuantity(int64(size)+delta.Value(), resource.BinarySI) + right := resource.NewQuantity(int64(size)+internal.ResizeDelta.Value(), resource.BinarySI) - equal := utils.AreSizesEqualWithinDelta(*left, *right, delta) + equal := utils.AreSizesEqualWithinDelta(*left, *right, internal.ResizeDelta) assert.False(t, equal) }) - }) } diff --git a/images/agent/src/pkg/controller/lvm_volume_group_discover_test.go b/images/agent/src/pkg/controller/lvm_volume_group_discover_test.go index 527b93d9..2b0f3ead 100644 --- a/images/agent/src/pkg/controller/lvm_volume_group_discover_test.go +++ b/images/agent/src/pkg/controller/lvm_volume_group_discover_test.go @@ -503,302 +503,97 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { t.Run("GetLVMVolumeGroup", func(t *testing.T) { const ( - LVMVGName = "test_lvm" - ActualVGNameOnTheNode = "test-vg" - Type = "local" - Health = internal.LVMVGHealthOperational - Message = "No problems detected" - VGUuid = "test_uuid" - ) - - size10G, err := resource.ParseQuantity("10G") - size1G, err := resource.ParseQuantity("1G") - if err != nil { - t.Error(err) - } - - var ( - cl = NewFakeClient() - testMetrics = monitoring.GetMetrics("") - testLogger = logger.Logger{} - ctx = context.Background() - blockDevicesNames = []string{"first", "second"} - specThinPools = map[string]resource.Quantity{"first": size10G} - statusThinPools = []internal.LVMVGStatusThinPool{ - { - Name: "first_status_pool", - ActualSize: size10G, - UsedSize: resource.MustParse("4G"), - }, - } - nodes = map[string][]internal.LVMVGDevice{ - "test-node-1": { - { - Path: "test/path", - PVSize: size1G, - DevSize: size1G, - PVUuid: "test-pv-uuid", - BlockDevice: "test-device", - }, - }, - } + LVMVGName = "test_lvm" ) - candidate := internal.LVMVolumeGroupCandidate{ - LVMVGName: LVMVGName, - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDevicesNames: blockDevicesNames, - SpecThinPools: specThinPools, - Type: Type, - AllocatedSize: size10G, - Health: Health, - Message: Message, - StatusThinPools: statusThinPools, - VGSize: size10G, - VGUuid: VGUuid, - Nodes: nodes, + lvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: LVMVGName, + }, } - - thinPools, err := convertStatusThinPools(v1alpha1.LvmVolumeGroup{}, statusThinPools) + err := cl.Create(ctx, lvg) if err != nil { t.Error(err) } - expected := map[string]v1alpha1.LvmVolumeGroup{ - LVMVGName: { - ObjectMeta: metav1.ObjectMeta{ - Name: LVMVGName, - ResourceVersion: "1", - OwnerReferences: nil, - }, - Spec: v1alpha1.LvmVolumeGroupSpec{ - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDeviceNames: blockDevicesNames, - ThinPools: convertSpecThinPools(specThinPools), - Type: Type, - }, - Status: v1alpha1.LvmVolumeGroupStatus{ - AllocatedSize: size10G, - Nodes: convertLVMVGNodes(nodes), - ThinPools: thinPools, - VGSize: size10G, - VGUuid: VGUuid, - }, - }, - } - - created, err := CreateLVMVolumeGroupByCandidate(ctx, testLogger, testMetrics, cl, candidate) - if assert.NoError(t, err) && assert.NotNil(t, created) { - actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) - if assert.NoError(t, err) && assert.Equal(t, 1, len(actual)) { - assert.Equal(t, expected, actual) + defer func() { + err = cl.Delete(ctx, lvg) + if err != nil { + t.Error(err) } + }() + + actual, err := GetAPILVMVolumeGroups(ctx, cl, monitoring.GetMetrics("test-node")) + if assert.NoError(t, err) { + _, ok := actual[LVMVGName] + assert.True(t, ok) } }) t.Run("DeleteLVMVolumeGroup", func(t *testing.T) { const ( - LVMVGName = "test_lvm" - ActualVGNameOnTheNode = "test-vg" - Type = "local" - Health = internal.LVMVGHealthOperational - Message = "No problems detected" - VGUuid = "test_uuid" + LVMVGName = "test_lvm-2" ) - size10G, err := resource.ParseQuantity("10G") - size1G, err := resource.ParseQuantity("1G") + metrics := monitoring.GetMetrics("test-node") + + lvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: LVMVGName, + }, + } + err := cl.Create(ctx, lvg) if err != nil { t.Error(err) } - var ( - cl = NewFakeClient() - ctx = context.Background() - testMetrics = monitoring.GetMetrics("") - testLogger = logger.Logger{} - blockDevicesNames = []string{"first", "second"} - specThinPools = map[string]resource.Quantity{"first": size10G} - statusThinPools = []internal.LVMVGStatusThinPool{ - { - Name: "first_status_pool", - ActualSize: size10G, - UsedSize: resource.MustParse("4G"), - }, - } - nodes = map[string][]internal.LVMVGDevice{ - "test-node-1": { - { - Path: "test/path", - PVSize: size1G, - DevSize: size1G, - PVUuid: "test-pv-uuid", - BlockDevice: "test-device", - }, - }, - } - ) - - candidate := internal.LVMVolumeGroupCandidate{ - LVMVGName: LVMVGName, - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDevicesNames: blockDevicesNames, - SpecThinPools: specThinPools, - Type: Type, - AllocatedSize: size10G, - Health: Health, - Message: Message, - StatusThinPools: statusThinPools, - VGSize: size10G, - VGUuid: VGUuid, - Nodes: nodes, + actual, err := GetAPILVMVolumeGroups(ctx, cl, metrics) + if assert.NoError(t, err) { + _, ok := actual[LVMVGName] + assert.True(t, ok) } - created, err := CreateLVMVolumeGroupByCandidate(ctx, testLogger, testMetrics, cl, candidate) - if assert.NoError(t, err) && assert.NotNil(t, created) { - actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) - if assert.NoError(t, err) && assert.Equal(t, 1, len(actual)) { - err := DeleteLVMVolumeGroup(ctx, cl, testMetrics, &v1alpha1.LvmVolumeGroup{ - ObjectMeta: metav1.ObjectMeta{ - Name: LVMVGName, - }, - }) - if assert.NoError(t, err) { - actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) - if assert.NoError(t, err) { - assert.Equal(t, 0, len(actual)) - } - } - } + err = DeleteLVMVolumeGroup(ctx, cl, log, metrics, lvg, "test-node") + if assert.NoError(t, err) { + actual, err = GetAPILVMVolumeGroups(ctx, cl, metrics) + assert.Equal(t, 0, len(actual)) } }) t.Run("UpdateLVMVolumeGroup", func(t *testing.T) { const ( - LVMVGName = "test_lvm" - ActualVGNameOnTheNode = "test-vg" - Type = "local" - Health = internal.LVMVGHealthOperational - Message = "No problems detected" - VGUuid = "test_uuid" - ) - - size10G, err := resource.ParseQuantity("10G") - size1G, err := resource.ParseQuantity("1G") - if err != nil { - t.Error(err) - } - - var ( - cl = NewFakeClient() - ctx = context.Background() - testMetrics = monitoring.GetMetrics("") - testLogger = logger.Logger{} - BlockDevicesNames = []string{"first", "second"} - SpecThinPools = map[string]resource.Quantity{"first": size1G} - StatusThinPools = []internal.LVMVGStatusThinPool{ - { - Name: "first_status_pool", - ActualSize: size10G, - UsedSize: resource.MustParse("4G"), - }, - } - oldNodes = map[string][]internal.LVMVGDevice{ - "test-node-1": { - { - Path: "test/path", - PVSize: size1G, - DevSize: size1G, - PVUuid: "test-pv-uuid", - BlockDevice: "test-device", - }, - }, - } - newNodes = map[string][]internal.LVMVGDevice{ - "test-node-1": { - { - Path: "test/path", - PVSize: size1G, - DevSize: size1G, - PVUuid: "test-pv-uuid", - BlockDevice: "test-device", - }, - { - Path: "test/path2", - PVSize: size1G, - DevSize: size1G, - PVUuid: "test-pv-uuid2", - BlockDevice: "test-device2", - }, - }, - } + LVMVGName = "test_lvm" ) - oldCandidate := internal.LVMVolumeGroupCandidate{ - LVMVGName: LVMVGName, - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDevicesNames: BlockDevicesNames, - SpecThinPools: SpecThinPools, - Type: Type, - AllocatedSize: size10G, - Health: Health, - Message: Message, - StatusThinPools: StatusThinPools, - VGSize: size10G, - VGUuid: VGUuid, - Nodes: oldNodes, - } + metrics := monitoring.GetMetrics("test-node") - newCandidate := internal.LVMVolumeGroupCandidate{ - LVMVGName: LVMVGName, - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDevicesNames: BlockDevicesNames, - SpecThinPools: SpecThinPools, - Type: Type, - AllocatedSize: size10G, - Health: Health, - Message: Message, - StatusThinPools: StatusThinPools, - VGSize: size10G, - VGUuid: VGUuid, - Nodes: newNodes, + lvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: LVMVGName, + }, } - - thinPools, err := convertStatusThinPools(v1alpha1.LvmVolumeGroup{}, StatusThinPools) + err := cl.Create(ctx, lvg) if err != nil { t.Error(err) } - expected := v1alpha1.LvmVolumeGroup{ - ObjectMeta: metav1.ObjectMeta{ - Name: LVMVGName, - ResourceVersion: "2", - OwnerReferences: nil, - }, - Spec: v1alpha1.LvmVolumeGroupSpec{ - ActualVGNameOnTheNode: ActualVGNameOnTheNode, - BlockDeviceNames: BlockDevicesNames, - ThinPools: convertSpecThinPools(SpecThinPools), - Type: Type, - }, - Status: v1alpha1.LvmVolumeGroupStatus{ - AllocatedSize: size10G, - Nodes: convertLVMVGNodes(newNodes), - ThinPools: thinPools, - VGSize: size10G, - VGUuid: VGUuid, - }, - } - - created, err := CreateLVMVolumeGroupByCandidate(ctx, testLogger, testMetrics, cl, oldCandidate) + actual, err := GetAPILVMVolumeGroups(ctx, cl, metrics) if assert.NoError(t, err) { - err := UpdateLVMVolumeGroupByCandidate(ctx, cl, testMetrics, log, created, newCandidate) + createdLvg, ok := actual[LVMVGName] + assert.True(t, ok) + candidate := internal.LVMVolumeGroupCandidate{ + LVMVGName: LVMVGName, + AllocatedSize: *resource.NewQuantity(1000, resource.BinarySI), + } + err = UpdateLVMVolumeGroupByCandidate(ctx, cl, metrics, log, &createdLvg, candidate) if assert.NoError(t, err) { - lmvs, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) + updated, err := GetAPILVMVolumeGroups(ctx, cl, metrics) if assert.NoError(t, err) { - actual := lmvs[LVMVGName] - assert.Equal(t, expected, actual) + updatedLvg, ok := updated[LVMVGName] + assert.True(t, ok) + + assert.Equal(t, candidate.AllocatedSize.Value(), updatedLvg.Status.AllocatedSize.Value()) } } } @@ -1000,25 +795,13 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }) t.Run("should_return_true", func(t *testing.T) { - size10G, err := resource.ParseQuantity("10G") - size1G, err := resource.ParseQuantity("1G") - size13G, err := resource.ParseQuantity("13G") - if err != nil { - t.Error(err) - } + size10G := resource.MustParse("10G") + size1G := resource.MustParse("1G") + size13G := resource.MustParse("13G") + vgFree := resource.MustParse("5G") var ( - blockDevicesNames = []string{ - "first", - "second", - } - specThinPools = map[string]resource.Quantity{ - "first": size10G, - "second": size1G, - } - specType = "type" allocatedSize = resource.MustParse("10G") - health = internal.LVMVGHealthOperational statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first", @@ -1052,15 +835,11 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { } ) candidate := internal.LVMVolumeGroupCandidate{ - BlockDevicesNames: blockDevicesNames, - SpecThinPools: specThinPools, - Type: specType, - AllocatedSize: size10G, - Health: health, - Message: "NewMessage", - StatusThinPools: statusThinPools, - VGSize: size10G, - Nodes: nodes, + AllocatedSize: size10G, + StatusThinPools: statusThinPools, + VGSize: size10G, + VGFree: vgFree, + Nodes: nodes, } thinPools, err := convertStatusThinPools(v1alpha1.LvmVolumeGroup{}, statusThinPools) @@ -1069,16 +848,12 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { } lvmVolumeGroup := v1alpha1.LvmVolumeGroup{ - Spec: v1alpha1.LvmVolumeGroupSpec{ - BlockDeviceNames: blockDevicesNames, - ThinPools: convertSpecThinPools(specThinPools), - Type: specType, - }, Status: v1alpha1.LvmVolumeGroupStatus{ AllocatedSize: allocatedSize, Nodes: convertLVMVGNodes(nodes), ThinPools: thinPools, VGSize: vgSize, + VGFree: *resource.NewQuantity(vgFree.Value()+10000, resource.BinarySI), }, } @@ -1126,8 +901,7 @@ func NewFakeClient() client.WithWatch { s := scheme.Scheme _ = metav1.AddMetaToScheme(s) _ = v1alpha1.AddToScheme(s) - - builder := fake.NewClientBuilder().WithScheme(s).WithStatusSubresource(&v1alpha1.LvmVolumeGroup{}) + builder := fake.NewClientBuilder().WithScheme(s).WithStatusSubresource(&v1alpha1.LvmVolumeGroup{}).WithStatusSubresource(&v1alpha1.LVMLogicalVolume{}) cl := builder.Build() return cl diff --git a/images/agent/src/pkg/controller/lvm_volume_group_test.go b/images/agent/src/pkg/controller/lvm_volume_group_test.go index 2cb0f1f6..cd8c4d31 100644 --- a/images/agent/src/pkg/controller/lvm_volume_group_test.go +++ b/images/agent/src/pkg/controller/lvm_volume_group_test.go @@ -115,11 +115,11 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { ThinPools: []v1alpha1.LvmVolumeGroupThinPoolSpec{ { Name: "test-name", - Size: *convertSize("10G", t), + Size: "10G", }, { Name: "test-name2", - Size: *convertSize("1G", t), + Size: "1G", }, }, }, @@ -176,164 +176,6 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { assert.Equal(t, expected, actual) } }) - - t.Run("Marshal_LvmVolumeGroup_struct_to_json", func(t *testing.T) { - expected := `{ - "apiVersion": "storage.deckhouse.io/v1alpha1", - "kind": "LvmVolumeGroup", - "metadata": { - "creationTimestamp": null, - "name": "lvg-test-1" - }, - "spec": { - "actualVGNameOnTheNode": "testVGname", - "blockDeviceNames": [ - "test-bd", - "test-bd2" - ], - "thinPools": [ - { - "name": "test-name", - "size": "10G" - }, - { - "name": "test-name2", - "size": "1G" - } - ], - "type": "local" - }, - "status": { - "conditions": null, - "allocatedSize": "20G", - "health": "operational", - "message": "all-good", - "nodes": [ - { - "devices": [ - { - "blockDevice": "test/BD", - "devSize": "1G", - "path": "test/path1", - "pvSize": "1G", - "pvUUID": "testPV1" - }, - { - "blockDevice": "test/BD2", - "devSize": "1G", - "path": "test/path2", - "pvSize": "2G", - "pvUUID": "testPV2" - } - ], - "name": "node1" - }, - { - "devices": [ - { - "blockDevice": "test/DB3", - "devSize": "2G", - "path": "test/path3", - "pvSize": "3G", - "pvUUID": "testPV3" - } - ], - "name": "node2" - } - ], - "phase": "", - "thinPools": [ - { - "name": "test-name", - "actualSize": "1G", - "usedSize": "500M", - "ready": true, - "message": "" - } - ], - "vgSize": "30G", - "vgUUID": "test-vg-uuid" - } -}` - testObj := v1alpha1.LvmVolumeGroup{ - ObjectMeta: metav1.ObjectMeta{ - Name: "lvg-test-1", - CreationTimestamp: metav1.Time{}, - }, - TypeMeta: metav1.TypeMeta{ - Kind: "LvmVolumeGroup", - APIVersion: "storage.deckhouse.io/v1alpha1", - }, - Spec: v1alpha1.LvmVolumeGroupSpec{ - ActualVGNameOnTheNode: "testVGname", - BlockDeviceNames: []string{"test-bd", "test-bd2"}, - ThinPools: []v1alpha1.LvmVolumeGroupThinPoolSpec{ - { - Name: "test-name", - Size: *convertSize("10G", t), - }, - { - Name: "test-name2", - Size: *convertSize("1G", t), - }, - }, - Type: "local", - }, - Status: v1alpha1.LvmVolumeGroupStatus{ - AllocatedSize: resource.MustParse("20G"), - Nodes: []v1alpha1.LvmVolumeGroupNode{ - { - Devices: []v1alpha1.LvmVolumeGroupDevice{ - { - BlockDevice: "test/BD", - DevSize: *convertSize("1G", t), - PVSize: resource.MustParse("1G"), - PVUuid: "testPV1", - Path: "test/path1", - }, - { - BlockDevice: "test/BD2", - DevSize: *convertSize("1G", t), - PVSize: resource.MustParse("2G"), - PVUuid: "testPV2", - Path: "test/path2", - }, - }, - Name: "node1", - }, - { - Devices: []v1alpha1.LvmVolumeGroupDevice{ - { - BlockDevice: "test/DB3", - DevSize: *convertSize("2G", t), - PVSize: resource.MustParse("3G"), - PVUuid: "testPV3", - Path: "test/path3", - }, - }, - Name: "node2", - }, - }, - ThinPools: []v1alpha1.LvmVolumeGroupThinPoolStatus{ - { - Name: "test-name", - ActualSize: *convertSize("1G", t), - UsedSize: resource.MustParse("500M"), - Ready: true, - Message: "", - }, - }, - VGSize: resource.MustParse("30G"), - VGUuid: "test-vg-uuid", - }, - } - - actual, err := json.Marshal(testObj) - - if assert.NoError(t, err) { - assert.JSONEq(t, expected, string(actual)) - } - }) } func convertSize(size string, t *testing.T) *resource.Quantity {