From 1127e89243318e7bad455a1768c46ab84ad07f0e Mon Sep 17 00:00:00 2001 From: Dmitry Bogun Date: Wed, 1 Feb 2017 15:41:32 +0200 Subject: [PATCH] Add additional functional tests These are a set of functional tests developed to test known issues and patches for those issues. It's better to keep these tests public, in case someone else faces functional degradation of bareon code. Change-Id: I17899f115df7f81786681ddb97db18cf2a01689a --- .../data_retention_blank_primary.xml | 55 +++ .../data_retention_with_unlabelled_disk.xml | 59 +++ .../node_templates/one_disk_persistent.xml | 55 +++ .../tests_functional/test_data_retention.py | 185 +++++++++ bareon/tests_functional/test_lvm.py | 3 - bareon/tests_functional/test_provisioning.py | 366 +++++++++++++++++- 6 files changed, 716 insertions(+), 7 deletions(-) create mode 100644 bareon/tests_functional/node_templates/data_retention_blank_primary.xml create mode 100644 bareon/tests_functional/node_templates/data_retention_with_unlabelled_disk.xml create mode 100644 bareon/tests_functional/node_templates/one_disk_persistent.xml diff --git a/bareon/tests_functional/node_templates/data_retention_blank_primary.xml b/bareon/tests_functional/node_templates/data_retention_blank_primary.xml new file mode 100644 index 0000000..837f8ee --- /dev/null +++ b/bareon/tests_functional/node_templates/data_retention_blank_primary.xml @@ -0,0 +1,55 @@ + +{{ node_name }} + 3145728 + 3145728 + 1 + + hvm + + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bareon/tests_functional/node_templates/data_retention_with_unlabelled_disk.xml b/bareon/tests_functional/node_templates/data_retention_with_unlabelled_disk.xml new file mode 100644 index 0000000..d1ed6f4 --- /dev/null +++ b/bareon/tests_functional/node_templates/data_retention_with_unlabelled_disk.xml @@ -0,0 +1,59 @@ + +{{ node_name }} + 3145728 + 3145728 + 1 + + hvm + + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bareon/tests_functional/node_templates/one_disk_persistent.xml b/bareon/tests_functional/node_templates/one_disk_persistent.xml new file mode 100644 index 0000000..8e9c8e0 --- /dev/null +++ b/bareon/tests_functional/node_templates/one_disk_persistent.xml @@ -0,0 +1,55 @@ + +{{ node_name }} + 3145728 + 3145728 + 1 + + hvm + + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + SomeSerialNumber +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + diff --git a/bareon/tests_functional/test_data_retention.py b/bareon/tests_functional/test_data_retention.py index 2db2c87..0af74ba 100644 --- a/bareon/tests_functional/test_data_retention.py +++ b/bareon/tests_functional/test_data_retention.py @@ -14,6 +14,9 @@ # limitations under the License. import copy +import json +import os +import tempfile from bareon import tests_functional from bareon.tests_functional import utils @@ -154,6 +157,108 @@ is included with the distribution media. self._assert_vda_equal_to_goldenimage(node) self._assert_vdb_equal_to_goldenimage(node) + def test_verify_policy_match_with_unlabelled_disk(self): + deploy_conf = { + "partitions": self.golden_image_schema, + "partitions_policy": "verify" + } + + self.env.patch_config_images(deploy_conf, 'test') + self.env.init_unlabelled_disk() + self.env.setup('data_retention_with_unlabelled_disk.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-partition --debug ' + '--data_driver ironic --deploy_driver swift', + check_ret_code=True, get_bareon_log=True) + + # Check that schema did not change after partitioning with verify + # policy. Check that extra disk (vdb) has not been verified/changed + # since not mentioned in schema (0 return code) + actual = node.run_cmd('parted -l')[0] + expected = """ +Model: Virtio Block Device (virtblk) +Disk /dev/vda: 11.8GB +Sector size (logical/physical): 512B/512B +Partition Table: gpt +Disk Flags: + +Number Start End Size File system Name Flags + 1 1049kB 26.2MB 25.2MB primary bios_grub + 2 26.2MB 4221MB 4194MB ext4 primary + 3 4221MB 6318MB 2097MB linux-swap(v1) primary + 4 6318MB 10.4GB 4089MB ext4 primary + + +Model: Virtio Block Device (virtblk) +Disk /dev/vdb: 106MB +Sector size (logical/physical): 512B/512B +Partition Table: loop +Disk Flags: + +Number Start End Size File system Flags + 1 0.00B 106MB 106MB ext4 + + +Model: Virtio Block Device (virtblk) +Disk /dev/vdc: 1049kB +Sector size (logical/physical): 512B/512B +Partition Table: unknown +Disk Flags: +""" # noqa + utils.assertNoDiff(expected, actual) + + self._assert_vda_equal_to_goldenimage(node) + self._assert_vdb_equal_to_goldenimage(node) + + def test_verify_policy_match_blank_primary(self): + # Deploy an image to /dev/vdb, with a second disk, not mentioned in + # the deploy schema, containing a blank primary partition located + # at /dev/vda. + deploy_conf = { + "partitions": self.golden_image_schema, + "partitions_policy": "verify" + } + deploy_conf['partitions'][0]['id']['value'] = 'vdb' + + self.env.patch_config_images(deploy_conf, 'test') + self.env.setup('data_retention_blank_primary.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-partition --debug ' + '--data_driver ironic --deploy_driver swift', + check_ret_code=True, get_bareon_log=True) + + # Check that schema did not change after partitioning with + # verify policy + actual = node.run_cmd('parted -l')[0] + expected = """ +Model: Virtio Block Device (virtblk) +Disk /dev/vda: 5243kB +Sector size (logical/physical): 512B/512B +Partition Table: gpt +Disk Flags: + +Number Start End Size File system Name Flags + 1 17.4kB 5226kB 5209kB ext4 primary + + +Model: Virtio Block Device (virtblk) +Disk /dev/vdb: 11.8GB +Sector size (logical/physical): 512B/512B +Partition Table: gpt +Disk Flags: + +Number Start End Size File system Name Flags + 1 1049kB 26.2MB 25.2MB primary bios_grub + 2 26.2MB 4221MB 4194MB ext4 primary + 3 4221MB 6318MB 2097MB linux-swap(v1) primary + 4 6318MB 10.4GB 4089MB ext4 primary +""" + utils.assertNoDiff(expected, actual) + def test_verify_policy_mismatch_extra_partition_in_schema(self): deploy_conf = { "partitions": copy.deepcopy(self.golden_image_schema), @@ -247,6 +352,86 @@ is included with the distribution media. self._assert_vdb_equal_to_goldenimage(node) + def test_verify_policy_preserve_fstab(self): + image = 'centos-7.1.1503.fpa_func_test.raw' + + deploy_conf = { + 'partitions_policy': 'clean', + 'partitions': [ + { + "type": "disk", + "id": { + "type": "name", + "value": "vda" + }, + "size": "10000 MiB", + "volumes": [ + { + "images": [image], + "type": "partition", + "mount": "/", + "file_system": "ext4", + "size": "4000 MiB", + "name": "test1" + } + ] + } + ] + } + + self.env.patch_config_images(deploy_conf, 'test') + self.env.patch_config_images(deploy_conf, image) + self.env.setup('data_retention.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-provision --debug ' + '--data_driver ironic --deploy_driver swift', + check_ret_code=True, get_bareon_log=True) + + extra_record = 'ftest-tmp /var/run tmpfs nodev,nosuid,noexec 0 0\n' + prefix = '/tmp/target' + fstab = os.path.join(prefix, 'etc/fstab') + + node.run_cmd('mount /dev/vda2 {}'.format(prefix), check_ret_code=True) + with tempfile.NamedTemporaryFile() as tmp: + node.get_file(fstab, tmp.name) + + tmp.seek(0, os.SEEK_END) + tmp.write('\n') + tmp.write(extra_record) + tmp.flush() + + node.put_file(tmp.name, fstab) + + with tempfile.NamedTemporaryFile() as tmp: + node.get_file('/tmp/provision.json', tmp.name) + tmp.seek(0, os.SEEK_SET) + deploy_conf = json.load(tmp) + deploy_conf['partitions_policy'] = 'verify' + + tmp.seek(0, os.SEEK_SET) + tmp.truncate() + json.dump(deploy_conf, tmp) + tmp.flush() + + node.put_file(tmp.name, '/tmp/provision.json') + + node.run_cmd('umount {}'.format(prefix), check_ret_code=True) + + node.run_cmd( + 'bareon-provision --debug ' + '--data_driver ironic --deploy_driver swift', + check_ret_code=True, get_bareon_log=True) + + node.run_cmd('mount /dev/vda2 {}'.format(prefix), check_ret_code=True) + with tempfile.NamedTemporaryFile() as tmp: + node.get_file(fstab, tmp.name) + + tmp.seek(0, os.SEEK_SET) + payload = tmp.readlines() + self.assertIn(extra_record, payload) + def test_clean_policy(self): deploy_conf = { "partitions": [ diff --git a/bareon/tests_functional/test_lvm.py b/bareon/tests_functional/test_lvm.py index d029212..4af4667 100644 --- a/bareon/tests_functional/test_lvm.py +++ b/bareon/tests_functional/test_lvm.py @@ -45,9 +45,6 @@ class LvmTestCase(tests_functional.TestCase): "type": "disk", "volumes": [ { - "images": [ - "test" - ], "vg": "rft_test_vg_2", "type": "pv", "size": "1976" # 2000 - 24 (GRUB stage 1.5) diff --git a/bareon/tests_functional/test_provisioning.py b/bareon/tests_functional/test_provisioning.py index 787131c..16554c4 100644 --- a/bareon/tests_functional/test_provisioning.py +++ b/bareon/tests_functional/test_provisioning.py @@ -12,14 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - import json -import utils import uuid +import os +import pytest from bareon import tests_functional +from bareon.tests_functional import utils class SingleProvisioningTestCase(tests_functional.TestCase): @@ -70,6 +70,7 @@ class SingleProvisioningTestCase(tests_functional.TestCase): } ] } + self.env.setup(node_template="two_disks.xml", deploy_config=deploy_conf) node = self.env.node @@ -79,7 +80,6 @@ class SingleProvisioningTestCase(tests_functional.TestCase): check_ret_code=True, get_bareon_log=True) - actual = node.run_cmd('parted -l')[0] expected = """ Model: Virtio Block Device (virtblk) Disk /dev/vda: 4295MB @@ -103,6 +103,7 @@ Number Start End Size File system Name Flags 2 26.2MB 1075MB 1049MB ext3 primary """ + actual = node.run_cmd('parted -l')[0] utils.assertNoDiff(expected, actual) self._update_cloud_conf(node) @@ -198,6 +199,363 @@ Number Start End Size File system Name Flags utils.assertNoDiff(expected, actual) + def test_provision_rsync_disk_by_id(self): + self.env.deploy_driver = 'rsync' + + deploy_conf = { + "images": [ + { + "name": "test", + "boot": True, + "target": "/", + "image_pull_url": self.env.get_url_for_image( + 'centos-7.1.1503.fpa_func_test.raw', + self.env.deploy_driver), + } + ], + "partitions_policy": "clean", + "partitions": [ + { + "id": {"type": "path", + "value": "disk/by-id/" + "ata-QEMU_HARDDISK_SomeSerialNumber"}, + "size": "3000", + "type": "disk", + "volumes": [ + { + "mount": "/", + "type": "partition", + "file_system": "ext4", + "size": "1400" + }, + { + "mount": "/usr", + "type": "partition", + "file_system": "ext4", + "size": "1500" + } + ], + + } + ] + } + + self.env.setup( + 'one_disk_persistent.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + actual = node.run_cmd('parted -l')[0] + expected = """ +Model: ATA QEMU HARDDISK (scsi) +Disk /dev/sda: 3221MB +Sector size (logical/physical): 512B/512B +Partition Table: gpt +Disk Flags: + +Number Start End Size File system Name Flags + 1 1049kB 26.2MB 25.2MB primary bios_grub + 2 26.2MB 1494MB 1468MB ext4 primary + 3 1494MB 3067MB 1573MB ext4 primary +""" + + utils.assertNoDiff(expected, actual) + + self._update_cloud_conf(node, part='vda2') + + node.reboot_to_hdd() + node.ssh_login = self.node_ssh_login + node.wait_for_boot() + + actual = node.run_cmd('uname -a')[0] + expected = ( + 'Linux fpa-func-test-tenant-vm 3.10.0-229.20.1.el7.x86_64' + ' #1 SMP Tue Nov 3 19:10:07 UTC 2015 x86_64 x86_64 x86_64' + ' GNU/Linux\n') + + utils.assertNoDiff(expected, actual) + + @pytest.mark.xfail + def test_provision_swift_verify(self): + """Test the behaviour of the verify partitions policy with Swift. + + First deploy a node using the clean policy, then change and create some + files on the provisioned file system. Finally, redeploy the same node + using the verify partitions policy. Following the redeployment, + modified files should be returned to their initial state, and newly + created files should be removed (due to block-level copy). + """ + self.env.deploy_driver = 'swift' + + deploy_conf = { + "images": [ + { + "name": "test", + "boot": True, + "target": "/", + "image_pull_url": self.env.get_url_for_image( + 'centos-7.1.1503.fpa_func_test.raw', + self.env.deploy_driver), + } + ], + "partitions_policy": "clean", + "partitions": [ + { + "id": {"type": "name", "value": "vda"}, + "size": "3000", + "type": "disk", + "volumes": [ + { + "mount": "/", + "type": "partition", + "file_system": "ext4", + "size": "2900" + } + ], + + } + ] + } + self.env.setup('one_disk.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Modify a file that isalready present on the image. + node.write_file("/dev/vda2", "etc/centos-release", "bogus release") + + # Write a file that don't exist in the image. + node.write_file("/dev/vda2", "new-file", "new content") + + # Update the deploy config to use the verify partitions policy. + deploy_conf["partitions_policy"] = "verify" + self.env.update_deploy_config(deploy_conf) + + # Deploy again. + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Verify that file present on the image is updated to its original + # state, and that changes are discarded. + actual_vda = node.read_file("/dev/vda2", "etc/centos-release") + expected_vda = "CentOS Linux release 7.1.1503 (Core) \n" + utils.assertNoDiff(expected_vda, actual_vda) + + # Verify that newly created file not on the image is not modified + # by the deployment. + actual_vda = node.read_file("/dev/vda2", "new-file") + expected_vda = "new content" + utils.assertNoDiff(expected_vda, actual_vda) + + def test_provision_rsync_verify(self): + """Test the behaviour of the verify partitions policy using rsync. + + First deploy a node using the clean policy, then change and create some + files on the provisioned file system. Finally, redeploy the same node + using the verify partitions policy. Following the redeployment, + modified files should be returned to their initial state, and newly + created files should be unchanged. + """ + self.env.deploy_driver = 'rsync' + + deploy_conf = { + "images": [ + { + "name": "test", + "boot": True, + "target": "/", + "image_pull_url": self.env.get_url_for_image( + 'centos-7.1.1503.fpa_func_test.raw', + self.env.deploy_driver), + } + ], + "partitions_policy": "clean", + "partitions": [ + { + "id": {"type": "name", "value": "vda"}, + "size": "3000", + "type": "disk", + "volumes": [ + { + "mount": "/", + "type": "partition", + "file_system": "ext4", + "size": "1400" + }, + { + "mount": "/usr", + "type": "partition", + "file_system": "ext4", + "size": "1500" + } + ], + } + ] + } + self.env.setup('one_disk.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Modify some files that are already present on the image in each + # partition. + node.write_file("/dev/vda2", "etc/centos-release", "bogus release") + node.write_file("/dev/vda3", "share/centos-release/EULA", + "bogus EULA") + + # Write some files that don't exist in the image on each partition. + node.write_file("/dev/vda2", "new-file", "new / content") + node.write_file("/dev/vda3", "new-file", "new /usr content") + + # Update the deploy config to use the verify partitions policy. + deploy_conf["partitions_policy"] = "verify" + self.env.update_deploy_config(deploy_conf) + + # Deploy again. + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Verify that files present on the image are updated to their original + # state, and that changes are discarded. + actual_vda_root = node.read_file("/dev/vda2", "etc/centos-release") + expected_vda_root = "CentOS Linux release 7.1.1503 (Core)" + utils.assertNoDiff(expected_vda_root, actual_vda_root) + + expected_vda_usr = (""" +CentOS-7 EULA + +CentOS-7 comes with no guarantees or warranties of any sorts, +either written or implied. + +The Distribution is released as GPLv2. Individual packages in the +distribution come with their own licences. A copy of the GPLv2 license +is included with the distribution media. + """) + actual_vda_usr = node.read_file("/dev/vda3", + "share/centos-release/EULA") + utils.assertNoDiff(expected_vda_usr, actual_vda_usr) + + # Verify that newly created files not on the image are not modified + # by the deployment. + actual_vda_root = node.read_file("/dev/vda2", "new-file") + expected_vda_root = "new / content" + utils.assertNoDiff(expected_vda_root, actual_vda_root) + + actual_vda_usr = node.read_file("/dev/vda3", "new-file") + expected_vda_usr = "new /usr content" + utils.assertNoDiff(expected_vda_usr, actual_vda_usr) + + def test_provision_rsync_verify_dry_run(self): + """Test the behaviour of the verify policy using an rsync dry run. + + First deploy a node using the clean policy, then change and create some + files on the provisioned file system. Finally, redeploy the same node + using the verify partitions policy and the --dry-run rsync flag. + Following the redeployment, modified and newly created files should be + unchanged. + """ + self.env.deploy_driver = 'rsync' + + deploy_conf = { + "images": [ + { + "name": "test", + "boot": True, + "target": "/", + "image_pull_url": self.env.get_url_for_image( + 'centos-7.1.1503.fpa_func_test.raw', + self.env.deploy_driver), + } + ], + "partitions_policy": "clean", + "partitions": [ + { + "id": {"type": "name", "value": "vda"}, + "size": "3000", + "type": "disk", + "volumes": [ + { + "mount": "/", + "type": "partition", + "file_system": "ext4", + "size": "1400" + }, + { + "mount": "/usr", + "type": "partition", + "file_system": "ext4", + "size": "1500" + } + ], + + } + ] + } + self.env.setup('one_disk.xml', deploy_conf) + node = self.env.node + + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Modify some files that are already present on the image in each + # partition. + node.write_file("/dev/vda2", "etc/centos-release", "bogus release") + node.write_file("/dev/vda3", "share/centos-release/EULA", + "bogus EULA") + + # Write some files that don't exist in the image on each partition. + node.write_file("/dev/vda2", "new-file", "new / content") + node.write_file("/dev/vda3", "new-file", "new /usr content") + + # Update the deploy config to use the verify partitions policy and the + # --dry-run rsync flag. + deploy_conf["partitions_policy"] = "verify" + deploy_conf["image_deploy_flags"] = { + "rsync_flags": "-a -A -X --timeout 300 --dry-run" + } + self.env.update_deploy_config(deploy_conf) + + # Deploy again. + node.run_cmd( + 'bareon-provision --data_driver ironic --deploy_driver {}'.format( + self.env.deploy_driver), + check_ret_code=True, get_bareon_log=True) + + # Verify that files present on the image are not modified by the + # deployment. + actual_vda_root = node.read_file("/dev/vda2", "etc/centos-release") + expected_vda_root = "bogus release" + utils.assertNoDiff(expected_vda_root, actual_vda_root) + expected_vda_usr = "bogus EULA" + actual_vda_usr = node.read_file("/dev/vda3", + "share/centos-release/EULA") + utils.assertNoDiff(expected_vda_usr, actual_vda_usr) + + # Verify that newly created files not on the image are not modified + # by the deployment. + actual_vda_root = node.read_file("/dev/vda2", "new-file") + expected_vda_root = "new / content" + utils.assertNoDiff(expected_vda_root, actual_vda_root) + actual_vda_usr = node.read_file("/dev/vda3", "new-file") + expected_vda_usr = "new /usr content" + utils.assertNoDiff(expected_vda_usr, actual_vda_usr) + def _update_cloud_conf(self, node, part='vda2'): # Update the cloud config in the tenant image to contain the # correct SSH public key. Normally this would be done from Ironic