diff --git a/.gitignore b/.gitignore
index ecfa440..d941817 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,5 @@ dist
.tox
.idea
.DS_Store
+.cache
*.egg-info
diff --git a/README.md b/README.md
index 019199d..99d7612 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ bareon
│ ├── drivers
│ ├── objects
│ ├── tests
+│ ├── tests_functional
│ ├── utils
├── README.md
├── LICENSE
diff --git a/bareon/tests_functional/__init__.py b/bareon/tests_functional/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bareon/tests_functional/image_build/centos_minimal.sh b/bareon/tests_functional/image_build/centos_minimal.sh
new file mode 100755
index 0000000..c99a37a
--- /dev/null
+++ b/bareon/tests_functional/image_build/centos_minimal.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+set -e
+
+if [ -n ${NO_DIB:-""} ] ; then
+ echo "================== NO_DIB passed. Skipping image build. =================="
+ exit 0
+fi
+
+echo "================== Rebuilding deploy images =================="
+
+source ${BUILD_ENV:-"bareon/tests_functional/image_build/centos_minimal_env.sh"}
+
+BAREON_PATH=$PWD
+
+rm -rf $BUILD_DIR
+mkdir $BUILD_DIR
+cd $BUILD_DIR
+
+# NOTE(lobur): temp workaround while we don't build the key along with the image
+wget $FUEL_KEY -O fuel_key
+chmod 0600 fuel_key
+
+git clone -b $DIB_BRANCH $DIB_SRC
+git clone -b $DIB_UTILS_BRANCH $DIB_UTILS_SRC
+git clone -b $DIB_ELEMENTS_BRANCH $DIB_ELEMENTS_SRC
+
+export PATH=$BUILD_DIR/diskimage-builder/bin:$BUILD_DIR/dib-utils/bin:$PATH
+
+export BAREON_SRC=file://$BAREON_PATH
+export BAREON_BRANCH=$(cd $BAREON_PATH && git rev-parse --abbrev-ref HEAD) # Use current branch
+
+export ELEMENTS_PATH=$BUILD_DIR/bareon-image-elements
+
+export DIB_OFFLINE=1
+export DIB_DEBUG_TRACE=1
+
+disk-image-create -n -t raw -o cent-min centos-minimal centos-bareon
+
+rm -r cent-min.raw
+mv cent-min.initramfs initramfs
+mv cent-min.vmlinuz vmlinuz
+
+echo "================== DONE Rebuilding deploy images =================="
+
+set +e
\ No newline at end of file
diff --git a/bareon/tests_functional/image_build/centos_minimal_env.sh b/bareon/tests_functional/image_build/centos_minimal_env.sh
new file mode 100644
index 0000000..ce715cc
--- /dev/null
+++ b/bareon/tests_functional/image_build/centos_minimal_env.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# A default environment used for image build/sync.
+
+export DIB_SRC=git@github.com:openstack/diskimage-builder.git
+export DIB_BRANCH=master
+
+export DIB_UTILS_SRC=git@github.com:openstack/dib-utils.git
+export DIB_UTILS_BRANCH=master
+
+export DIB_ELEMENTS_SRC=git@github.com:openstack/bareon-image-elements.git
+export DIB_ELEMENTS_BRANCH=master
+
+export FUEL_KEY=https://raw.githubusercontent.com/stackforge/fuel-main/master/bootstrap/ssh/id_rsa
+export BUILD_DIR=/tmp/rft_image_build
+
+export GOLDEN_IMAGE_DIR=/tmp/rft_golden_images/
+export GOLDEN_IMAGE_SRC=http://images.fuel-infra.org/rft_golden_images/
\ No newline at end of file
diff --git a/bareon/tests_functional/image_build/sync_golden_images.sh b/bareon/tests_functional/image_build/sync_golden_images.sh
new file mode 100644
index 0000000..46bbab4
--- /dev/null
+++ b/bareon/tests_functional/image_build/sync_golden_images.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+set -e
+
+if [ -n ${NO_SYNC:-""} ] ; then
+ echo " ================== NO_SYNC passed. Skipping the rsync of the golden images. =================="
+ exit 0
+fi
+
+source ${BUILD_ENV:-"bareon/tests_functional/image_build/centos_minimal_env.sh"}
+
+# NOTE(lobur): This is not actually syncing images (-nc). If image has changed
+# it won't catch that. So to get the new image you need to manually clean the
+# GOLDEN_IMAGE_DIR or remove that particular image before running the script.
+echo "================== Getting golden images from server =================="
+wget -r -P $GOLDEN_IMAGE_DIR -nc -nH --cut-dirs=2 --no-parent --reject "index.html*" $GOLDEN_IMAGE_SRC
+echo "================== DONE Getting golden images from server =================="
+
+set +e
diff --git a/bareon/tests_functional/node_templates/__init__.py b/bareon/tests_functional/node_templates/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bareon/tests_functional/node_templates/data_retention.xml b/bareon/tests_functional/node_templates/data_retention.xml
new file mode 100644
index 0000000..1439641
--- /dev/null
+++ b/bareon/tests_functional/node_templates/data_retention.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/one_disk.xml b/bareon/tests_functional/node_templates/one_disk.xml
new file mode 100644
index 0000000..93fdb8e
--- /dev/null
+++ b/bareon/tests_functional/node_templates/one_disk.xml
@@ -0,0 +1,50 @@
+
+{{ node_name }}
+ 3145728
+ 3145728
+ 1
+
+ hvm
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bareon/tests_functional/node_templates/two_disks.xml b/bareon/tests_functional/node_templates/two_disks.xml
new file mode 100644
index 0000000..81f2a4b
--- /dev/null
+++ b/bareon/tests_functional/node_templates/two_disks.xml
@@ -0,0 +1,52 @@
+
+{{ node_name }}
+ 3145728
+ 3145728
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bareon/tests_functional/node_templates/two_disks_multiboot.xml b/bareon/tests_functional/node_templates/two_disks_multiboot.xml
new file mode 100644
index 0000000..0ce7f85
--- /dev/null
+++ b/bareon/tests_functional/node_templates/two_disks_multiboot.xml
@@ -0,0 +1,52 @@
+
+{{ node_name }}
+ 3145728
+ 3145728
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bareon/tests_functional/test_data_retention.py b/bareon/tests_functional/test_data_retention.py
new file mode 100644
index 0000000..ee6a9c9
--- /dev/null
+++ b/bareon/tests_functional/test_data_retention.py
@@ -0,0 +1,396 @@
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest2
+import utils
+
+from ramdisk_func_test.environment import Environment
+
+
+class DataRetentionTestCase(unittest2.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(DataRetentionTestCase, cls).setUpClass()
+ cls.env = Environment(
+ node_templates="./bareon/tests_functional/node_templates"
+ )
+ cls.env.setupclass()
+
+ def setUp(self):
+ super(DataRetentionTestCase, self).setUp()
+ self.images = [
+ {
+ "name": "test",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": "",
+ }
+ ]
+ self.golden_image_schema = [
+ {
+ "type": "disk",
+ "id": {
+ "type": "name",
+ "value": "vda"
+ },
+ "size": "10000 MiB",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "partition",
+ "mount": "/",
+ "file_system": "ext4",
+ "size": "4000 MiB",
+ "name": "test1"
+ },
+ {
+ "images": [
+ "test"
+ ],
+ "type": "partition",
+ "mount": "swap",
+ "file_system": "swap",
+ "size": "2000 MiB",
+ "name": "swap"
+ },
+ {
+ "images": [
+ "test"
+ ],
+ "type": "partition",
+ "mount": "/usr",
+ "file_system": "ext4",
+ "size": "3900 MiB",
+ "name": "test2"
+ }
+ ]
+ }
+ ]
+
+ self.golden_image_parted_output = """
+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
+"""
+
+ def tearDown(self):
+ super(DataRetentionTestCase, self).tearDown()
+ self.env.teardown()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(DataRetentionTestCase, cls).tearDownClass()
+ cls.env.teardownclass()
+
+ def _assert_vda_equal_to_goldenimage(self, node):
+ self._assert_vda_root_equal_to_goldenimage(node)
+ self._assert_vda_usr_equal_to_goldenimage(node)
+
+ def _assert_vda_root_equal_to_goldenimage(self, node):
+ # Roughly checking that vda / partition not changed
+ actual_vda = node.read_file("/dev/vda2", "etc/centos-release")
+ expected_vda = "CentOS Linux release 7.1.1503 (Core)"
+ utils.assertNoDiff(expected_vda, actual_vda)
+
+ def _assert_vda_usr_equal_to_goldenimage(self, node):
+ # Roughly checking that vda /usr partition not changed
+ actual_vda = node.read_file("/dev/vda4", "share/centos-release/EULA")
+ expected_vda = """
+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.
+"""
+ utils.assertNoDiff(expected_vda, actual_vda)
+
+ def _assert_vdb_equal_to_goldenimage(self, node):
+ # Checking that vdb golden image contents are not erased
+ actual_vdb = node.read_file("/dev/vdb", "test-content")
+ expected_vdb = "test content"
+ utils.assertNoDiff(expected_vdb, actual_vdb)
+
+ def test_verify_policy_match(self):
+ deploy_conf = {
+ "images": self.images,
+ "partitions": self.golden_image_schema,
+ "partitions_policy": "verify"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ 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 = self.golden_image_parted_output
+ utils.assertNoDiff(expected, actual)
+
+ self._assert_vda_equal_to_goldenimage(node)
+ self._assert_vdb_equal_to_goldenimage(node)
+
+ def test_verify_policy_mismatch_extra_partition_in_schema(self):
+ self.golden_image_schema[0]["volumes"].append({
+ "images": [
+ "test"
+ ],
+ "mount": "/tmp",
+ "type": "partition",
+ "file_system": "ext3",
+ "size": "2000"
+ })
+ deploy_conf = {
+ "images": self.images,
+ "partitions": self.golden_image_schema,
+ "partitions_policy": "verify"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ out, ret_code = node.run_cmd(
+ 'bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ get_bareon_log=True)
+ self.assertEqual(255, ret_code)
+
+ # Check that schema did not change after partitioning with
+ # verify policy
+ actual = node.run_cmd('parted -l')[0]
+ expected = self.golden_image_parted_output
+ utils.assertNoDiff(expected, actual)
+
+ self._assert_vda_equal_to_goldenimage(node)
+ self._assert_vdb_equal_to_goldenimage(node)
+
+ def test_verify_policy_mismatch_extra_partition_on_hw(self):
+ last_partition = self.golden_image_schema[0]['volumes'][-1]
+ self.golden_image_schema[0]['volumes'].remove(last_partition)
+
+ deploy_conf = {
+ "images": self.images,
+ "partitions": self.golden_image_schema,
+ "partitions_policy": "verify"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ out, ret_code = node.run_cmd(
+ 'bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ get_bareon_log=True)
+ self.assertEqual(255, ret_code)
+
+ # Check that schema did not change after partitioning with
+ # verify policy
+ actual = node.run_cmd('parted -l')[0]
+ expected = self.golden_image_parted_output
+ utils.assertNoDiff(expected, actual)
+
+ self._assert_vda_equal_to_goldenimage(node)
+ self._assert_vdb_equal_to_goldenimage(node)
+
+ def test_verify_policy_match_and_clean_one_of_filesystems(self):
+ usr_partition = self.golden_image_schema[0]['volumes'][2]
+ self.assertEqual('/usr', usr_partition['mount'])
+ usr_partition['keep_data'] = False
+
+ deploy_conf = {
+ "images": self.images,
+ "partitions": self.golden_image_schema,
+ "partitions_policy": "verify"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ get_bareon_log=True)
+
+ # Check that schema did not change after partitioning with
+ # verify policy
+ actual = node.run_cmd('parted -l')[0]
+ expected = self.golden_image_parted_output
+ utils.assertNoDiff(expected, actual)
+
+ self._assert_vda_root_equal_to_goldenimage(node)
+ # Check vda /usr has been erased
+ out, ret_code = node.run_cmd('mount -t ext4 /dev/vda4 /mnt && '
+ 'ls /mnt && '
+ 'umount /mnt')
+ utils.assertNoDiff("lost+found", out)
+
+ self._assert_vdb_equal_to_goldenimage(node)
+
+ def test_clean_policy(self):
+ deploy_conf = {
+ "images": [
+ {
+ "name": "test",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": "",
+ }
+ ],
+ "partitions": [
+ {
+ "type": "disk",
+ "id": {
+ "type": "name",
+ "value": "vda"
+ },
+ "size": "10000",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "partition",
+ "mount": "/",
+ "file_system": "ext3",
+ "size": "6000",
+ "name": "test1"
+ }
+ ]
+ }
+ ],
+ "partitions_policy": "clean"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ # Check that schema has been applied (to vda only)
+ 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 6318MB 6291MB ext3 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
+"""
+ utils.assertNoDiff(expected, actual)
+
+ self._assert_vdb_equal_to_goldenimage(node)
+
+ def test_clean_policy_disk_too_small(self):
+ # Tries to deploy to a disk which is too small for the schema.
+ # The Fuel agent should throw:
+ # NotEnoughSpaceError: Partition scheme for: /dev/vdb exceeds the size
+ # of the disk. Scheme size is 150 MB, and disk size is 106.303488 MB.
+ deploy_conf = {
+ "images": [
+ {
+ "name": "test",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": "",
+ }
+ ],
+ "partitions": [
+ {
+ "type": "disk",
+ "id": {
+ "type": "name",
+ "value": "vdb"
+ },
+ "size": "150",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "partition",
+ "mount": "/",
+ "file_system": "ext3",
+ "size": "100",
+ "name": "test1"
+ }
+ ]
+ }
+ ],
+ "partitions_policy": "clean"
+ }
+
+ self.env.setup(node_template="data_retention.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ # Return code should be 255 due to the agent throwing an exception
+ out, ret_code = node.run_cmd(
+ 'bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ check_ret_code=False, get_bareon_log=True)
+ self.assertEqual(255, ret_code)
+
+ # Nothing should have changed
+ self._assert_vdb_equal_to_goldenimage(node)
diff --git a/bareon/tests_functional/test_lvm.py b/bareon/tests_functional/test_lvm.py
new file mode 100644
index 0000000..62d8401
--- /dev/null
+++ b/bareon/tests_functional/test_lvm.py
@@ -0,0 +1,312 @@
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest2
+import utils
+
+from ramdisk_func_test.environment import Environment
+
+
+class LvmTestCase(unittest2.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(LvmTestCase, cls).setUpClass()
+ cls.env = Environment(
+ node_templates="./bareon/tests_functional/node_templates"
+ )
+ cls.env.setupclass()
+
+ def tearDown(self):
+ super(LvmTestCase, self).tearDown()
+ self.env.teardown()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(LvmTestCase, cls).tearDownClass()
+ cls.env.teardownclass()
+
+ def test_multi_volume_multi_group(self):
+ deploy_conf = {
+ "images": [
+ {
+ "name": "test",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": "",
+ }
+ ],
+ "partitions_policy": "clean",
+ "partitions": [
+ {
+ "id": {"type": "name", "value": "vda"},
+ "size": "3000",
+ "type": "disk",
+ "volumes": [
+ {
+ "vg": "fpa_test_vg_1",
+ "type": "pv",
+ "size": "2000"
+ },
+ {
+ "vg": "fpa_test_vg_2",
+ "type": "pv",
+ "size": "976" # 1000 - 24 (GRUB stage 1.5)
+ }
+ ],
+ },
+ {
+ "id": {"type": "name", "value": "vdb"},
+ "size": "2000",
+ "type": "disk",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "vg": "fpa_test_vg_2",
+ "type": "pv",
+ "size": "1976" # 2000 - 24 (GRUB stage 1.5)
+ },
+ ],
+ },
+ {
+ "type": "vg",
+ "id": "fpa_test_vg_1",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_root_vol",
+ "mount": "/",
+ "size": "1000",
+ "file_system": "ext4"
+ },
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_var_vol",
+ "mount": "/var",
+ "size": "936", # (2000-1000)- 1*64 (lvm meta)
+ "file_system": "ext3"
+ }
+ ]
+ },
+ {
+ "type": "vg",
+ "id": "fpa_test_vg_2",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_usr_vol",
+ "mount": "/usr",
+ "size": "2000",
+ "file_system": "ext4"
+ },
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_etc_vol",
+ "mount": "/etc",
+ "size": "824", # (976+1976)-2000-2*64 (lvm meta)
+ "file_system": "ext3"
+ }
+ ]
+ }
+ ]
+ }
+ self.env.setup(node_template="two_disks.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ actual = node.run_cmd('parted -lm && pvs && lvs')[0]
+ expected = """
+BYT;
+/dev/mapper/fpa_test_vg_2-fpa_etc_vol:864MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:864MB:864MB:ext3::;
+
+BYT;
+/dev/mapper/fpa_test_vg_2-fpa_usr_vol:2097MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:2097MB:2097MB:ext4::;
+
+BYT;
+/dev/mapper/fpa_test_vg_1-fpa_var_vol:981MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:981MB:981MB:ext3::;
+
+BYT;
+/dev/mapper/fpa_test_vg_1-fpa_root_vol:1049MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:1049MB:1049MB:ext4::;
+
+BYT;
+/dev/vda:4295MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:2123MB:2097MB::primary:;
+3:2123MB:3147MB:1023MB::primary:;
+
+BYT;
+/dev/vdb:2147MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:2098MB:2072MB::primary:;
+
+ PV VG Fmt Attr PSize PFree
+ /dev/vda2 fpa_test_vg_1 lvm2 a-- 1.89g 4.00m
+ /dev/vda3 fpa_test_vg_2 lvm2 a-- 916.00m 8.00m
+ /dev/vdb2 fpa_test_vg_2 lvm2 a-- 1.87g 0
+ LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
+ fpa_root_vol fpa_test_vg_1 -wi-a----- 1000.00m
+ fpa_var_vol fpa_test_vg_1 -wi-a----- 936.00m
+ fpa_etc_vol fpa_test_vg_2 -wi-a----- 824.00m
+ fpa_usr_vol fpa_test_vg_2 -wi-a----- 1.95g
+""""" # noqa
+ utils.assertNoDiff(expected, actual)
+
+ def test_mixed_partitions_and_lvs(self):
+ deploy_conf = {
+ "images": [
+ {
+ "name": "test",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": "",
+ }
+ ],
+ "partitions_policy": "clean",
+ "partitions": [
+ {
+ "id": {"type": "name", "value": "vda"},
+ "size": "3000",
+ "type": "disk",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "mount": "/",
+ "type": "partition",
+ "file_system": "ext4",
+ "size": "2476" # 2500 - 24 (GRUB stage 1.5)
+ },
+ {
+ "vg": "fpa_test_vg_1",
+ "type": "pv",
+ "size": "500"
+ }
+ ],
+ },
+ {
+ "id": {"type": "name", "value": "vdb"},
+ "size": "2000",
+ "type": "disk",
+ "volumes": [
+ {
+ "vg": "fpa_test_vg_1",
+ "type": "pv",
+ "size": "976" # 1000 - 24 (GRUB stage 1.5)
+ },
+ {
+ "vg": "fpa_test_vg_2",
+ "type": "pv",
+ "size": "1000"
+ },
+ ],
+ },
+ {
+ "type": "vg",
+ "id": "fpa_test_vg_1",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_usr_vol",
+ "mount": "/usr",
+ "size": "1348", # (976+500) - 2*64 (lvm meta)
+ "file_system": "ext3"
+ }
+ ]
+ },
+ {
+ "type": "vg",
+ "id": "fpa_test_vg_2",
+ "volumes": [
+ {
+ "images": [
+ "test"
+ ],
+ "type": "lv",
+ "name": "fpa_opt_vol",
+ "mount": "/opt",
+ "size": "936", # 1000 - 1*64 (lvm meta)
+ "file_system": "ext4"
+ }
+ ]
+ }
+ ]
+ }
+ self.env.setup(node_template="two_disks.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-partition --data_driver ironic '
+ '--deploy_driver swift --debug',
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ actual = node.run_cmd('parted -lm && pvs && lvs')[0]
+ expected = """
+BYT;
+/dev/mapper/fpa_test_vg_2-fpa_opt_vol:981MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:981MB:981MB:ext4::;
+
+BYT;
+/dev/mapper/fpa_test_vg_1-fpa_usr_vol:1413MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:1413MB:1413MB:ext3::;
+
+BYT;
+/dev/vda:4295MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:2622MB:2596MB:ext4:primary:;
+3:2622MB:3147MB:524MB::primary:;
+
+BYT;
+/dev/vdb:2147MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:1050MB:1023MB::primary:;
+3:1050MB:2098MB:1049MB::primary:;
+
+ PV VG Fmt Attr PSize PFree
+ /dev/vda3 fpa_test_vg_1 lvm2 a-- 440.00m 8.00m
+ /dev/vdb2 fpa_test_vg_1 lvm2 a-- 916.00m 0
+ /dev/vdb3 fpa_test_vg_2 lvm2 a-- 940.00m 4.00m
+ LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
+ fpa_usr_vol fpa_test_vg_1 -wi-a----- 1.32g
+ fpa_opt_vol fpa_test_vg_2 -wi-a----- 936.00m
+""" # noqa
+ utils.assertNoDiff(expected, actual)
diff --git a/bareon/tests_functional/test_nailgun.py b/bareon/tests_functional/test_nailgun.py
new file mode 100644
index 0000000..3b3ef4f
--- /dev/null
+++ b/bareon/tests_functional/test_nailgun.py
@@ -0,0 +1,319 @@
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from copy import deepcopy
+
+import unittest2
+import utils
+
+from ramdisk_func_test.environment import Environment
+
+
+PROVISION_SAMPLE_DATA = {
+ "profile": "pro_fi-le",
+ "name_servers_search": "\"domain.tld\"",
+ "uid": "1",
+ "interfaces": {
+ "eth2": {
+ "static": "0",
+ "mac_address": "08:00:27:b1:d7:15"
+ },
+ "eth1": {
+ "static": "0",
+ "mac_address": "08:00:27:46:43:60"
+ },
+ "eth0": {
+ "ip_address": "10.20.0.3",
+ "dns_name": "node-1.domain.tld",
+ "netmask": "255.255.255.0",
+ "static": "0",
+ "mac_address": "08:00:27:79:da:80"
+ }
+ },
+ "interfaces_extra": {
+ "eth2": {
+ "onboot": "no",
+ "peerdns": "no"
+ },
+ "eth1": {
+ "onboot": "no",
+ "peerdns": "no"
+ },
+ "eth0": {
+ "onboot": "yes",
+ "peerdns": "no"
+ }
+ },
+ "power_type": "ssh",
+ "power_user": "root",
+ "kernel_options": {
+ "udevrules": "08:00:27:79:da:80_eth0,08:00:27:46:43:60_eth1,"
+ "08:00:27:b1:d7:15_eth2",
+ "netcfg/choose_interface": "08:00:27:79:da:80"
+ },
+ "power_address": "10.20.0.253",
+ "name_servers": "\"10.20.0.2\"",
+ "ks_meta": {
+ "gw": "10.20.0.1",
+ "image_data": {
+ "/": {
+ "uri": "",
+ "format": "ext4",
+ "container": "raw"
+ }
+ },
+ "timezone": "America/Los_Angeles",
+ "master_ip": "10.20.0.2",
+ "mco_enable": 1,
+ "mco_vhost": "mcollective",
+ "mco_pskey": "unset",
+ "mco_user": "mcollective",
+ "puppet_enable": 0,
+ "fuel_version": "5.0.1",
+ "install_log_2_syslog": 1,
+ "mco_password": "marionette",
+ "puppet_auto_setup": 1,
+ "puppet_master": "fuel.domain.tld",
+ "mco_auto_setup": 1,
+ "auth_key": "fake_auth_key",
+ "authorized_keys": ["fake_authorized_key1", "fake_authorized_key2"],
+ "repo_setup": {
+ "repos": [
+ {
+ "name": "repo1",
+ "type": "deb",
+ "uri": "uri1",
+ "suite": "suite",
+ "section": "section",
+ "priority": 1001
+ },
+ {
+ "name": "repo2",
+ "type": "deb",
+ "uri": "uri2",
+ "suite": "suite",
+ "section": "section",
+ "priority": 1001
+ }
+ ]
+ },
+ "pm_data": {
+ "kernel_params": "console=ttyS0,9600 console=tty0 rootdelay=90 "
+ "nomodeset",
+ "ks_spaces": [
+ {
+ "name": "vda",
+ "extra": [],
+ "free_space": 4000,
+ "volumes": [
+ {
+ "size": 2600,
+ "mount": "/",
+ "type": "partition",
+ "file_system": "ext4",
+ "name": "root"
+ },
+ {
+ "mount": "/tmp",
+ "size": 200,
+ "type": "partition",
+ "file_system": "ext2",
+ "name": "TMP"
+ },
+ {
+ "type": "lvm_meta_pool",
+ "size": 0
+ },
+ {
+ "size": 1000,
+ "type": "pv",
+ "lvm_meta_size": 64,
+ "vg": "image"
+ }
+ ],
+ "type": "disk",
+ "id": "vda",
+ "size": 4000
+ },
+ {
+ "name": "vdb",
+ "extra": [],
+ "free_space": 2000,
+ "volumes": [
+ {
+ "type": "lvm_meta_pool",
+ "size": 64
+ },
+ {
+ "size": 500,
+ "type": "pv",
+ "lvm_meta_size": 64,
+ "vg": "os"
+ },
+ {
+ "size": 1300,
+ "type": "pv",
+ "lvm_meta_size": 64,
+ "vg": "image"
+ }
+ ],
+ "type": "disk",
+ "id": "sdb",
+ "size": 2000
+ },
+ {
+ "_allocate_size": "min",
+ "label": "Base System",
+ "min_size": 400,
+ "volumes": [
+ {
+ "mount": "swap",
+ "size": 400,
+ "type": "lv",
+ "name": "swap",
+ "file_system": "swap"
+ }
+ ],
+ "type": "vg",
+ "id": "os"
+ },
+ {
+ "_allocate_size": "min",
+ "label": "Zero size volume",
+ "min_size": 0,
+ "volumes": [
+ {
+ "mount": "none",
+ "size": 0,
+ "type": "lv",
+ "name": "zero_size",
+ "file_system": "xfs"
+ }
+ ],
+ "type": "vg",
+ "id": "zero_size"
+ },
+ {
+ "_allocate_size": "all",
+ "label": "Image Storage",
+ "min_size": 2100,
+ "volumes": [
+ {
+ "mount": "/var/lib/glance",
+ "size": 2100,
+ "type": "lv",
+ "name": "glance",
+ "file_system": "xfs"
+ }
+ ],
+ "type": "vg",
+ "id": "image"
+ }
+ ]
+ },
+ "mco_connector": "rabbitmq",
+ "mco_host": "10.20.0.2"
+ },
+ "name": "node-1",
+ "hostname": "node-1.domain.tld",
+ "slave_name": "node-1",
+ "power_pass": "/root/.ssh/bootstrap.rsa",
+ "netboot_enabled": "1"
+}
+
+
+class TestNailgun(unittest2.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestNailgun, cls).setUpClass()
+ cls.env = Environment(
+ node_templates="./bareon/tests_functional/node_templates"
+ )
+ cls.env.setupclass()
+
+ def tearDown(self):
+ super(TestNailgun, self).tearDown()
+ self.env.teardown()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestNailgun, cls).tearDownClass()
+ cls.env.teardownclass()
+
+ def test_provision(self):
+ data = deepcopy(PROVISION_SAMPLE_DATA)
+ data['ks_meta']['image_data']['/']['uri'] = self.env.get_url_for_image(
+ 'centos-7.1.1503.fpa_func_test.raw',
+ 'swift')
+
+ self.env.setup(node_template="two_disks.xml",
+ deploy_config=data)
+ node = self.env.node
+
+ node.run_cmd('bareon-provision --data_driver nailgun '
+ '--deploy_driver nailgun',
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ actual = node.run_cmd('parted -lm && pvs && lvs')[0]
+ expected = """
+BYT;
+/dev/mapper/image-glance:2202MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:2202MB:2202MB:xfs::;
+
+BYT;
+/dev/mapper/os-swap:419MB:dm:512:512:loop:Linux device-mapper (linear):;
+1:0.00B:419MB:419MB:linux-swap(v1)::;
+
+BYT;
+/dev/vda:4295MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:236MB:210MB::primary:;
+3:236MB:2962MB:2726MB:ext4:primary:;
+4:2962MB:3172MB:210MB:ext2:primary:;
+5:3172MB:4221MB:1049MB::primary:;
+
+BYT;
+/dev/vdb:2147MB:virtblk:512:512:gpt:Virtio Block Device:;
+1:1049kB:26.2MB:25.2MB::primary:bios_grub;
+2:26.2MB:236MB:210MB::primary:;
+3:236MB:760MB:524MB::primary:;
+4:760MB:2123MB:1363MB::primary:;
+
+ PV VG Fmt Attr PSize PFree
+ /dev/vda5 image lvm2 a-- 940.00m 80.00m
+ /dev/vdb3 os lvm2 a-- 440.00m 40.00m
+ /dev/vdb4 image lvm2 a-- 1.21g 0
+ LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
+ glance image -wi-a----- 2.05g
+ swap os -wi-a----- 400.00m
+""" # noqa
+ utils.assertNoDiff(expected, actual)
+
+ # TODO(lobur): Cloud init failure (readonly filesystem /var/lib/..)
+ # Thus no ssh key added, cannot check further
+
+ # node.reboot_to_hdd()
+ # node.wait_for_boot()
+ #
+ # node.ssh_login = "centos"
+ # actual = node.run_cmd('uname -a')[0]
+ # expected = (
+ # 'Linux rft-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)
diff --git a/bareon/tests_functional/test_provisioning.py b/bareon/tests_functional/test_provisioning.py
new file mode 100644
index 0000000..828b19c
--- /dev/null
+++ b/bareon/tests_functional/test_provisioning.py
@@ -0,0 +1,301 @@
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import unittest2
+import utils
+import uuid
+
+from ramdisk_func_test.environment import Environment
+
+
+class SingleProvisioningTestCase(unittest2.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(SingleProvisioningTestCase, cls).setUpClass()
+ cls.env = Environment(
+ node_templates="./bareon/tests_functional/node_templates"
+ )
+ cls.env.setupclass()
+
+ def tearDown(self):
+ super(SingleProvisioningTestCase, self).tearDown()
+ self.env.teardown()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(SingleProvisioningTestCase, cls).tearDownClass()
+ cls.env.teardownclass()
+
+ def test_provision_two_disks_swift(self):
+ 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',
+ DEPLOY_DRIVER),
+ }
+ ],
+ "partitions_policy": "clean",
+ "partitions": [
+ {
+ "id": {"type": "name", "value": "vda"},
+ "size": "4000",
+ "type": "disk",
+ "volumes": [
+ {
+ "mount": "/",
+ "type": "partition",
+ "file_system": "ext4",
+ "size": "3000"
+ }
+ ],
+
+ },
+ {
+ "id": {"type": "name", "value": "vdb"},
+ "size": "2000",
+ "type": "disk",
+ "volumes": [
+ {
+ "mount": "/home",
+ "type": "partition",
+ "file_system": "ext3",
+ "size": "1000"
+ }
+ ],
+
+ }
+ ]
+ }
+ self.env.setup(node_template="two_disks.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-provision --data_driver ironic '
+ '--deploy_driver %s' % DEPLOY_DRIVER,
+ 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
+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 3172MB 3146MB ext4 primary
+
+
+Model: Virtio Block Device (virtblk)
+Disk /dev/vdb: 2147MB
+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 1075MB 1049MB ext3 primary
+"""
+
+ utils.assertNoDiff(expected, actual)
+
+ node.reboot_to_hdd()
+ node.wait_for_boot()
+
+ # Set node.ssh_key to "path to tenant key"
+ # (if tenant key is different than deploy key)
+ node.ssh_login = "centos"
+ 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)
+
+ def test_provision_rsync(self):
+ 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',
+ 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(node_template="one_disk.xml",
+ deploy_config=deploy_conf)
+ node = self.env.node
+
+ node.run_cmd('bareon-provision --data_driver ironic '
+ '--deploy_driver %s' % DEPLOY_DRIVER,
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ actual = node.run_cmd('parted -l')[0]
+ expected = """
+Model: Virtio Block Device (virtblk)
+Disk /dev/vda: 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)
+
+ node.reboot_to_hdd()
+ node.wait_for_boot()
+
+ # Set node.ssh_key to "path to tenant key"
+ # (if tenant key is different than deploy key)
+ node.ssh_login = "centos"
+ 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)
+
+
+class MultipleProvisioningTestCase(unittest2.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(MultipleProvisioningTestCase, cls).setUpClass()
+ cls.env = Environment(
+ node_templates="./bareon/tests_functional/node_templates"
+ )
+ cls.env.setupclass()
+
+ def tearDown(self):
+ super(MultipleProvisioningTestCase, self).tearDown()
+ self.env.teardown()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(MultipleProvisioningTestCase, cls).tearDownClass()
+ cls.env.teardownclass()
+
+ def test_multiple_provisioning(self):
+ DEPLOY_DRIVER = 'swift'
+ image_url = self.env.get_url_for_image(
+ "centos-7.1.1503.fpa_func_test.raw", DEPLOY_DRIVER)
+
+ deploy_conf = {
+ "images": [
+ {
+ "name": "centos",
+ "boot": True,
+ "target": "/",
+ "image_pull_url": image_url,
+ },
+ {
+ "name": "ubuntu",
+ "boot": False,
+ "target": "/",
+ "image_pull_url": image_url,
+ },
+ ],
+ "partitions_policy": "clean",
+ "partitions": [
+ {
+ "id": {"type": "name", "value": "vda"},
+ "size": "4000",
+ "type": "disk",
+ "volumes": [
+ {
+ "mount": "/",
+ "images": [
+ "centos"
+ ],
+ "type": "partition",
+ "file_system": "ext4",
+ "size": "3000"
+ }
+ ],
+
+ },
+ {
+ "id": {"type": "name", "value": "vdb"},
+ "size": "4000",
+ "type": "disk",
+ "volumes": [
+ {
+ "mount": "/",
+ "images": [
+ "ubuntu"
+ ],
+ "type": "partition",
+ "file_system": "ext4",
+ "size": "3000"
+ }
+ ],
+
+ }
+ ]
+ }
+ self.env.setup(node_template="two_disks_multiboot.xml",
+ deploy_config=deploy_conf)
+
+ node = self.env.node
+
+ node.run_cmd('bareon-provision --data_driver ironic '
+ '--deploy_driver %s' % DEPLOY_DRIVER,
+ check_ret_code=True,
+ get_bareon_log=True)
+
+ actual = node.run_cmd('cat /tmp/boot_entries.json')[0]
+
+ actual_data = json.loads(actual)
+ self.assertEqual(len(actual_data.get('elements')), 2)
+ uuid.UUID(actual_data.get('multiboot_partition'))
diff --git a/bareon/tests_functional/utils.py b/bareon/tests_functional/utils.py
new file mode 100644
index 0000000..064d39c
--- /dev/null
+++ b/bareon/tests_functional/utils.py
@@ -0,0 +1,24 @@
+#
+# Copyright 2016 Cray Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from bareon.utils import utils
+
+
+def assertNoDiff(expected, actual):
+ diff = utils.text_diff(expected, actual,
+ sfrom="expected", sto="actual")
+ if diff:
+ print(diff)
+ raise AssertionError
diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst
index 1728a61..106cbc6 100644
--- a/doc/source/contributing.rst
+++ b/doc/source/contributing.rst
@@ -2,3 +2,217 @@
Contributing
============
.. include:: ../../CONTRIBUTING.rst
+
+
+------------------
+Functional testing
+------------------
+
+Overview
+--------
+
+Bareon Agent functional testing performed against a kernel/ramdisk
+built on CentOS minimal. By default the image is built as part of tox command,
+using DIB. Option to use pre-built images available.
+Tests are written using unittest2 and Functional Test Framework
+(ramdisk-func-test). The framework itself uses libvirt (python bindings) to
+configure network, spawn a slave VM running ramdisk. In future we may add
+support for baremetal slaves. Framework resides in a standalone repo.
+Functional tests, as well as commonly changed parts of test data (node
+templates, etc) are located in bareon tree, so that each
+pull request introducing the new functionality to bareon can also carry
+corresponding functional tests update.
+
+
+How to run tests (Devstack / CentOS 7.1 environment)
+----------------------------------------------------
+
+- Build the devstack environment
+- Install additional dependencies:
+
+.. code-block:: console
+
+ $ sudo yum install yum-utils.noarch
+
+- Disable GPG check at the epel repo:
+
+ ::
+
+ [epel]
+ name=Extra Packages for Enterprise Linux 7 - $basearch
+ #baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
+ mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
+ failovermethod=priority
+ enabled=1
+ gpgcheck=0
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
+
+
+- Install ramdisk-func-test from source:
+
+.. code-block:: console
+
+ $ cd /opt/stack/
+ $ git clone git@github.com:openstack/ramdisk-func-test.git
+ $ cd ramdisk-func-test
+ $ sudo python setup.py develop
+
+- Configure ramdisk-func-test framework
+
+.. code-block:: console
+
+ # Create config
+ $ sudo mkdir /etc/ramdisk-func-test
+ $ sudo chown $USER:$USER /etc/ramdisk-func-test
+ $ touch /etc/ramdisk-func-test/ramdisk-func-test.conf
+
+ # Open port for the Ironic API stub
+ $ sudo iptables -I INPUT -p tcp --dport 8011 -j ACCEPT
+
+ # Configure rsync daemon
+ $ python ramdisk-func-test/tools/setup_rsync.py
+
+
+- Get bareon source:
+
+.. code-block:: console
+
+ $ cd /opt/stack/
+ $ git clone git@github.com:openstack/bareon.git
+
+- Run tests
+
+.. code-block:: console
+
+ $ cd /opt/stack/bareon
+ # Build image & run all tests
+ $ tox
+ # Build image & run only functional tests
+ $ tox -efunc
+ # Run only functional tests without image rebuild (assuming you already
+ # have images at /tmp/rft_image_build)
+ $ NO_DIB=1 tox -efunc
+ # Run only functional tests without syncing golden images with server
+ $ NO_SYNC=1 tox -efunc
+ # Run a single functional test:
+ $ tox -efunc bareon/tests_functional/test_data_retention.py::DataRetentionTestCase::test_clean_policy
+
+
+How to run tests (Clean CentOS environment, e.g. CI slave)
+----------------------------------------------------------
+
+- Provision CI slave
+- Install tox, and other dependencies:
+
+.. code-block:: console
+
+ $ sudo pip install tox
+ $ sudo yum install yum-utils.noarch
+ $ sudo yum install dib-utils # Use newt-provided noarch rpm
+
+- If local KVM is going to be used to run slaves (nested virtualization)
+
+.. note:: Currently this is a required step (no support for remote qemu)
+
+.. code-block:: console
+
+ $ sudo yum install libvirt
+ $ sudo yum install libvirt-python
+ $ echo 'auth_unix_ro = "none"' | sudo tee -a /etc/libvirt/libvirtd.conf
+ $ echo 'auth_unix_rw = "none"' | sudo tee -a /etc/libvirt/libvirtd.conf
+ $ /bin/systemctl start libvirtd.service
+
+- Install ramdisk-func-test from source:
+
+.. code-block:: console
+
+ $ cd /opt/stack/
+ $ git clone git@github.com:openstack/ramdisk-func-test.git
+ $ cd ramdisk-func-test
+ # If this job is triggered by pull request to ramdisk-func-test, checkout
+ # PR source branch git checkout
+ # Otherwise use master
+ $ sudo python setup.py develop
+
+- Configure ramdisk-func-test framework
+
+.. code-block:: console
+
+ # Create config
+ $ sudo mkdir /etc/ramdisk-func-test
+ $ sudo chown $USER:$USER /etc/ramdisk-func-test
+ $ cp ~/ramdisk-func-test/etc/ramdisk-func-test/ramdisk-func-test.conf.sample \
+ /etc/ramdisk-func-test/ramdisk-func-test.conf
+
+ # Open port for the Ironic API stub
+ $ sudo iptables -I INPUT -p tcp --dport 8011 -j ACCEPT
+
+ # Configure rsync daemon
+ $ cd ramdisk-func-test && sudo python tools/setup_rsync.py
+
+- Get bareon source:
+
+.. code-block:: console
+
+ $ cd /opt/stack/
+ $ git clone git@github.com:openstack/bareon.git
+ # If this job is triggered by pull request to bareon, checkout PR source branch
+ $ git checkout
+ # Otherwise use master
+ $ git checkout newt/kilo
+
+- Configure image build environment If needed (example below). Otherwise default is used.
+- Run all tests
+
+.. code-block:: console
+
+ $ cd ~/bareon
+ $ tox
+
+
+Customizing image build environment
+-----------------------------------
+A default environment file could be found at
+bareon/tests_functional/image_build/centos_minimal_env.sh
+
+You can override these with your own environment. To run tests using a custom
+environment:
+
+.. code-block:: console
+
+ $ export BUILD_ENV=/path/to/my_bareon_env.sh
+
+
+Using pre-built images
+----------------------
+- Make sure images are at /tmp/rft_image_build and named initramfs and vmlinuz
+- Make sure the fuel_key is at /tmp/rft_image_build
+- Use the following command to run tests:
+
+.. code-block:: console
+
+ $ cd ~/bareon
+ $ NO_DIB=1 tox
+
+
+Updating golden images
+----------------------
+According to the https://bugs.launchpad.net/fuel/+bug/1549368 golden images
+are hosted at http://images.fuel-infra.org/rft_golden_images/
+
+To update existing golden images you need to put them on two hosts. Make sure
+you have the key and proper ssh config.
+
+
+.. code-block:: console
+
+ $ cat ~/.ssh/config
+
+ Host fuel-infra-images
+ HostName seed-*.fuel-infra.org
+ User images
+ identityfile ~/.ssh/golden_images_key_rsa
+
+ $ cd /tmp/rft_golden_images
+ $ rsync -av --progress . images@seed-cz1.fuel-infra.org:/var/www/images/rft_golden_images/ &
+ $ rsync -av --progress . images@seed-us1.fuel-infra.org:/var/www/images/rft_golden_images/ &
diff --git a/test-requirements.txt b/test-requirements.txt
index 16f0089..8921a16 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,7 +6,6 @@ mock>=1.2 # BSD
requests-mock>=0.7.0 # Apache-2.0
unittest2 # BSD
pytest>=2.7.2
-pytest-cov>=1.8.1
# this is required for the docs build jobs
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
diff --git a/tox.ini b/tox.ini
index b4566f8..2e44208 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
[tox]
minversion = 1.6
skipsdist = True
-envlist = py34,py27,pep8
+envlist = py27,py34,func,pep8
[testenv]
usedevelop = True
@@ -31,6 +31,17 @@ commands = {posargs:}
envdir = devenv
usedevelop = True
+[testenv:func]
+sitepackages=True
+install_command = pip install --allow-external -U {opts} {packages}
+deps = -r{toxinidir}/test-requirements.txt
+whitelist_externals = bash
+passenv = BUILD_ENV SSH_AUTH_SOCK NO_SYNC NO_DIB
+commands =
+ bash bareon/tests_functional/image_build/sync_golden_images.sh
+ bash bareon/tests_functional/image_build/centos_minimal.sh
+ py.test -xvv {posargs:bareon/tests_functional}
+
[testenv:docs]
commands = python setup.py build_sphinx