Make get_partitions() work for partitioned disks
In general case, attached disks could be partitioned,
and this leads to multiple records in /proc/partitions,
for my laptop which is:
evgeny@eantyshev2:~$ cat /proc/partitions
major minor #blocks name
8 0 125034840 sda
8 1 524288 sda1
8 2 249856 sda2
8 3 124259328 sda3
8 16 976762584 sdb
11 0 1048575 sr0
252 0 1084366848 dm-0
252 1 16650240 dm-1
QEMU adds block devices as unpartitioned disks, so that
we have 1 disk <-> 1 partition match. But this is just
an implementation specific coincidence.
Because the attached disk can have GPT table
and a primary partition covering available disk space, and in this
case it would mean 2 extra devices.
Namely, to run Tempest on Virtuozzo containers, we should allow for
partitioned disks attached.
CT-f9e98104 /# cat /proc/partitions
major minor #blocks name
182 686608 2097152 ploop42913
182 686609 2095104 ploop42913p1
182 506688 1048576 ploop31668
182 506689 1046528 ploop31668p1
Here we see 2 devices for each disk: root disk block device ploop31668,
and partition block device ploop31668p1. We only want to see
root device for each disk, not the partition ones, or
some testcases don't work
(test_verify_created_server_ephemeral_disk naturally expects
device appearance of 1 extra device).
Change-Id: Icd0043b661c41a51acf62cc07cb80c2e9bae56d4
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 2f43157..a05cb89 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -312,7 +312,7 @@
self.validation_resources['keypair']['private_key'],
server=server_no_eph_disk,
servers_client=self.client)
- partition_num = len(linux_client.get_partitions().split('\n'))
+ disks_num = len(linux_client.get_disks().split('\n'))
# Explicit server deletion necessary for Juno compatibility
self.client.delete_server(server_no_eph_disk['id'])
@@ -332,8 +332,8 @@
self.validation_resources['keypair']['private_key'],
server=server_with_eph_disk,
servers_client=self.client)
- partition_num_emph = len(linux_client.get_partitions().split('\n'))
- self.assertEqual(partition_num + 1, partition_num_emph)
+ disks_num_eph = len(linux_client.get_disks().split('\n'))
+ self.assertEqual(disks_num + 1, disks_num_eph)
class ServersTestManualDisk(ServersTestJSON):
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index d4831b1..4ba9c5e 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -109,9 +109,9 @@
server=server,
servers_client=self.servers_client)
- partitions = linux_client.get_partitions()
- device_name_to_match = ' ' + self.device + '\n'
- self.assertIn(device_name_to_match, partitions)
+ disks = linux_client.get_disks()
+ device_name_to_match = '\n' + self.device + ' '
+ self.assertIn(device_name_to_match, disks)
self._detach(server['id'], volume['id'])
self.attachment = None
@@ -132,8 +132,8 @@
server=server,
servers_client=self.servers_client)
- partitions = linux_client.get_partitions()
- self.assertNotIn(device_name_to_match, partitions)
+ disks = linux_client.get_disks()
+ self.assertNotIn(device_name_to_match, disks)
@test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
def test_list_get_volume_attachments(self):
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 9ec217f..d8993bb 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -112,11 +112,22 @@
output = self.exec_command('grep -c ^processor /proc/cpuinfo')
return int(output)
- def get_partitions(self):
- # Return the contents of /proc/partitions
- command = 'cat /proc/partitions'
+ def get_disks(self):
+ # Select root disk devices as shown by lsblk
+ command = 'lsblk -lb --nodeps'
output = self.exec_command(command)
- return output
+ selected = []
+ pos = None
+ for l in output.splitlines():
+ if pos is None and l.find("TYPE") > 0:
+ pos = l.find("TYPE")
+ # Show header line too
+ selected.append(l)
+ # lsblk lists disk type in a column right-aligned with TYPE
+ elif pos > 0 and l[pos:pos + 4] == "disk":
+ selected.append(l)
+
+ return "\n".join(selected)
def get_boot_time(self):
cmd = 'cut -f1 -d. /proc/uptime'
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 3ac6759..bf52211 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -66,10 +66,10 @@
waiters.wait_for_server_status(self.servers_client,
server['id'], 'ACTIVE')
- def check_partitions(self):
+ def check_disks(self):
# NOTE(andreaf) The device name may be different on different guest OS
- partitions = self.linux_client.get_partitions()
- self.assertEqual(1, partitions.count(CONF.compute.volume_device_name))
+ disks = self.linux_client.get_disks()
+ self.assertEqual(1, disks.count(CONF.compute.volume_device_name))
def create_and_add_security_group_to_server(self, server):
secgroup = self._create_security_group()
@@ -145,7 +145,7 @@
self.linux_client = self.get_remote_client(
floating_ip['ip'], private_key=keypair['private_key'])
- self.check_partitions()
+ self.check_disks()
# delete the floating IP, this should refresh the server addresses
self.compute_floating_ips_client.delete_floating_ip(floating_ip['id'])
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 0f2c78c..dff00e7 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -85,9 +85,9 @@
ssh = self.get_remote_client(ip_address, private_key=private_key)
def _func():
- part = ssh.get_partitions()
- LOG.debug("Partitions:%s" % part)
- return CONF.compute.volume_device_name in part
+ disks = ssh.get_disks()
+ LOG.debug("Disks: %s" % disks)
+ return CONF.compute.volume_device_name in disks
if not test_utils.call_until_true(_func,
CONF.compute.build_timeout,
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index e59e08f..e4f4c04 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -107,13 +107,20 @@
self.assertEqual(self.conn.get_number_of_vcpus(), 16)
self._assert_exec_called_with('grep -c ^processor /proc/cpuinfo')
- def test_get_partitions(self):
- proc_partitions = """major minor #blocks name
+ def test_get_disks(self):
+ output_lsblk = """\
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+sda 8:0 0 128035676160 0 disk
+sdb 8:16 0 1000204886016 0 disk
+sr0 11:0 1 1073741312 0 rom"""
+ result = """\
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+sda 8:0 0 128035676160 0 disk
+sdb 8:16 0 1000204886016 0 disk"""
-8 0 1048576 vda"""
- self.ssh_mock.mock.exec_command.return_value = proc_partitions
- self.assertEqual(self.conn.get_partitions(), proc_partitions)
- self._assert_exec_called_with('cat /proc/partitions')
+ self.ssh_mock.mock.exec_command.return_value = output_lsblk
+ self.assertEqual(self.conn.get_disks(), result)
+ self._assert_exec_called_with('lsblk -lb --nodeps')
def test_get_boot_time(self):
booted_at = 10000