From 36ab4e943d82c5de307b5a7f3d23f2494e2e3ec5 Mon Sep 17 00:00:00 2001 From: Teddy Andrieux Date: Tue, 23 Mar 2021 15:42:57 +0100 Subject: [PATCH] salt/tests: Add unit tests for new LVM LV volumes New volume type get added in storage-operator and metalk8s_volumes salt execution module so add unit tests about it Refs: #1997 --- .../modules/files/test_metalk8s_volumes.yaml | 174 ++++++++++++++++++ .../unit/modules/test_metalk8s_volumes.py | 26 ++- 2 files changed, 195 insertions(+), 5 deletions(-) diff --git a/salt/tests/unit/modules/files/test_metalk8s_volumes.yaml b/salt/tests/unit/modules/files/test_metalk8s_volumes.yaml index 5c4e5dbcc0..5075676d1d 100644 --- a/salt/tests/unit/modules/files/test_metalk8s_volumes.yaml +++ b/salt/tests/unit/modules/files/test_metalk8s_volumes.yaml @@ -137,6 +137,30 @@ _volumes_details: &volumes_details lastUpdateTime: '2020-07-11T13:55:26Z' status: 'True' type: Ready + my-lvm-lv-volume: + apiVersion: storage.metalk8s.scality.com/v1alpha1 + kind: Volume + metadata: + name: my-lvm-lv-volume + uid: 6474cda7-0dbe-40fc-9842-3cb0404a725a + spec: + nodeName: bootstrap + storageClass: + metadata: + name: metalk8s-monitoring + mount_options: + - rw + - discard + parameters: + fsType: ext4 + mkfsOptions: '["-m", "0"]' + provisioner: kubernetes.io/no-provisioner + reclaim_policy: Retain + volume_binding_mode: WaitForFirstConsumer + storageClassName: metalk8s-monitoring + LVMLogicalVolume: + vgName: my_vg + size: 10Gi my-sparse-block-volume: apiVersion: storage.metalk8s.scality.com/v1alpha1 kind: Volume @@ -258,6 +282,31 @@ _volumes_details: &volumes_details storageClassName: xfs-storage-class rawBlockDevice: devicePath: /dev/sda2 + my-lvm-lv-block-volume: + apiVersion: storage.metalk8s.scality.com/v1alpha1 + kind: Volume + metadata: + name: my-lvm-lv-block-volume + uid: 7474cda7-0dbe-40fc-9842-3cb0404a725a + spec: + nodeName: bootstrap + storageClass: + metadata: + name: metalk8s-monitoring + mount_options: + - rw + - discard + parameters: + fsType: ext4 + mkfsOptions: '["-m", "0"]' + provisioner: kubernetes.io/no-provisioner + reclaim_policy: Retain + volume_binding_mode: WaitForFirstConsumer + storageClassName: metalk8s-monitoring + mode: Block + LVMLogicalVolume: + vgName: my_vg + size: 10Gi my-invalid-storage-class-volume: apiVersion: storage.metalk8s.scality.com/v1alpha1 kind: Volume @@ -391,6 +440,36 @@ exists: is_blkdev: False result: False + ## LVM LogicalVolume volumes + # specified LVM Logical Volume exists + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + lvdisplay: + /dev/my_vg/my-lvm-lv-volume: + a: lot + of: useful informations + result: True + + # specified LVM Logical Volume does not exists + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + result: False + + ## LVM LogicalVolume block volumes + # specified LVM Logical Volume exists + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + lvdisplay: + /dev/my_vg/my-lvm-lv-block-volume: + a: lot + of: useful informations + result: True + + # specified LVM Logical Volume does not exists + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + result: False + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume @@ -454,6 +533,28 @@ create: # We do not need to create block device raise_msg: block device /dev/dm-1 does not exists + ## LVM LogicalVolume volume + # create a simple LVM LV volume + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + + # unable to create the LVM LV + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + lvcreate: null + raise_msg: "cannot create LVM LV my-lvm-lv-volume in VG my_vg" + + ## LVM LogicalVolume block volume + # create a simple LVM LV volume + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + + # unable to create the LVM LV + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + lvcreate: null + raise_msg: "cannot create LVM LV my-lvm-lv-block-volume in VG my_vg" + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume @@ -555,6 +656,25 @@ is_prepared: pillar_volumes: *volumes_details result: True + ## LVM LogicalVolume volume + # LVM LV already prepared - right UUID + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + uuid_return: 6474cda7-0dbe-40fc-9842-3cb0404a725a + result: True + + # LVM LogicalVolume already prepared - wrong UUID + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + uuid_return: e1d78810-3787-4ca4-b712-50a269e42560 + result: False + + ## LVM LogicalVolume block volume + # block lvm volume always prepared (nothing to prepare) + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + result: True + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume @@ -645,6 +765,22 @@ prepare: - name: my-raw-block-device-block-lvm-volume pillar_volumes: *volumes_details + ## LVM LogicalVolume volume + # prepare the LVM LV volume in ext4 + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + cmd_output: | + + # error when formatting the LVM LV in ext4 + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + raise_msg: "error while trying to run `mkfs.ext4 -F .* /dev/my_vg/my-lvm-lv-volume`: An error has occurred" + + ## LVM LogicalVolume block lvm volume + # Nothing to prepare for block lvm volume + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + ## Invalid volumes # volume with invalid storage class name - name: my-invalid-storage-class-volume @@ -710,6 +846,18 @@ is_cleaned_up: pillar_volumes: *volumes_details result: True + ## LVM LogicalVolume volume + # LVM LV always cleaned up (we do not remove the LV) + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + result: True + + ## LVM LogicalVolume block volume + # LVM LV block always cleaned up (we do not remove the LV) + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + result: True + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume @@ -770,6 +918,16 @@ clean_up: - name: my-raw-block-device-block-lvm-volume pillar_volumes: *volumes_details + ## LVM LogicalVolume volume + # nothing to clean up (we do not remove the LV) + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + + ## LVM LogicalVolume block volume + # nothing to clean up (we do not remove the LV) + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume @@ -825,6 +983,22 @@ device_info: size: 4242 path: /dev/dm-1 + ## LVM LogicalVolume volume + # LVM LogicalVolume info + - name: my-lvm-lv-volume + pillar_volumes: *volumes_details + result: + size: 4242 + path: /dev/disk/by-uuid/6474cda7-0dbe-40fc-9842-3cb0404a725a + + ## LVM LogicalVolume block volume + # LVM LogicalVolume block info + - name: my-lvm-lv-block-volume + pillar_volumes: *volumes_details + result: + size: 4242 + path: /dev/dm-2 + ## Invalid volumes # specified volume is not in the pillar - name: unknown-volume diff --git a/salt/tests/unit/modules/test_metalk8s_volumes.py b/salt/tests/unit/modules/test_metalk8s_volumes.py index f023bf6f8e..d41467e441 100644 --- a/salt/tests/unit/modules/test_metalk8s_volumes.py +++ b/salt/tests/unit/modules/test_metalk8s_volumes.py @@ -20,6 +20,8 @@ def device_name_mock(path): + if path.startswith("/dev/my_vg/"): + path = "dm-2" return {"success": True, "result": os.path.basename(path)} @@ -46,13 +48,17 @@ def test_exists( is_file=True, get_size=1073741824, is_blkdev=True, + lvdisplay=None, ): """ Tests the return of `exists` function """ pillar_dict = {"metalk8s": {"volumes": pillar_volumes or {}}} - salt_dict = {"file.is_blkdev": MagicMock(return_value=is_blkdev)} + salt_dict = { + "file.is_blkdev": MagicMock(return_value=is_blkdev), + "lvm.lvdisplay": MagicMock(return_value=lvdisplay or {}), + } is_file_mock = MagicMock(return_value=is_file) get_size_mock = MagicMock(return_value=get_size) @@ -77,7 +83,9 @@ def test_exists( self.assertEqual(metalk8s_volumes.exists(name), result) @utils.parameterized_from_cases(YAML_TESTS_CASES["create"]) - def test_create(self, name, raise_msg=None, pillar_volumes=None, ftruncate=True): + def test_create( + self, name, raise_msg=None, pillar_volumes=None, ftruncate=True, lvcreate=True + ): """ Tests the return of `create` function """ @@ -90,9 +98,17 @@ def test_create(self, name, raise_msg=None, pillar_volumes=None, ftruncate=True) # Glob is used only for lvm, let simulate that we have 2 lvm volume glob_mock = MagicMock(return_value=["/dev/dm-1", "/dev/dm-2"]) - with patch.dict(metalk8s_volumes.__pillar__, pillar_dict), patch( - "metalk8s_volumes.device_name", device_name_mock - ), patch("glob.glob", glob_mock), patch("os.open", MagicMock()), patch( + lvcreate_mock = MagicMock(return_value=lvcreate) + if not lvcreate: + lvcreate_mock.side_effect = Exception("Banana") + + with patch.dict(metalk8s_volumes.__pillar__, pillar_dict), patch.dict( + metalk8s_volumes.__salt__, {"lvm.lvcreate": lvcreate_mock} + ), patch("metalk8s_volumes.device_name", device_name_mock), patch( + "glob.glob", glob_mock + ), patch( + "os.open", MagicMock() + ), patch( "os.unlink", MagicMock() ), patch( "os.ftruncate", ftruncate_mock