Skip to content

Commit

Permalink
Move metalsmith_instances from tripleo-ansible
Browse files Browse the repository at this point in the history
Change-Id: I02407547154d8d6084fa30c5fe164c5b6a060043
  • Loading branch information
steveb committed Jul 1, 2020
1 parent 53636ba commit 62b8b1d
Show file tree
Hide file tree
Showing 5 changed files with 623 additions and 0 deletions.
1 change: 1 addition & 0 deletions lower-constraints.txt
@@ -1,3 +1,4 @@
ansible==2.8.12
appdirs==1.4.3
certifi==2020.4.5.1
cffi==1.14.0
Expand Down
252 changes: 252 additions & 0 deletions metalsmith/test/test_metalsmith_instances.py
@@ -0,0 +1,252 @@
# Copyright 2019 Red Hat, 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 unittest
from unittest import mock

from metalsmith_ansible.ansible_plugins.modules \
import metalsmith_instances as mi

from metalsmith import exceptions as exc


class TestMetalsmithInstances(unittest.TestCase):

@mock.patch('metalsmith.sources.detect', autospec=True)
def test_get_source(self, mock_detect):
mi._get_source({
'image': {'href': 'overcloud-full'}
})
mi._get_source({
'image': {
'href': 'file://overcloud-full.qcow2',
'checksum': 'asdf',
'kernel': 'file://overcloud-full.vmlinuz',
'ramdisk': 'file://overcloud-full.initrd'
}
})
mock_detect.assert_has_calls([
mock.call(
image='overcloud-full',
checksum=None,
kernel=None,
ramdisk=None
),
mock.call(
image='file://overcloud-full.qcow2',
checksum='asdf',
kernel='file://overcloud-full.vmlinuz',
ramdisk='file://overcloud-full.initrd'
)
])

def test_reserve(self):
provisioner = mock.Mock()
instances = [{
'name': 'node',
'resource_class': 'boxen',
'capabilities': {'foo': 'bar'},
'traits': ['this', 'that'],
'conductor_group': 'group'
}, {}]
reserved = [
mock.Mock(id=1),
mock.Mock(id=2),
]

# test reserve success
provisioner.reserve_node.side_effect = reserved

result = mi.reserve(provisioner, instances, True)
provisioner.reserve_node.assert_has_calls([
mock.call(
candidates=['node'],
capabilities={'foo': 'bar'},
conductor_group='group',
resource_class='boxen',
traits=['this', 'that']
),
mock.call(
candidates=None,
capabilities=None,
conductor_group=None,
resource_class='baremetal',
traits=None
)
])
self.assertTrue(result[0])
self.assertEqual(reserved, result[1])

# test reserve failure with cleanup
instances = [{}, {}, {}]
reserved = [
mock.Mock(id=1),
mock.Mock(id=2),
exc.ReservationFailed('ouch')
]
provisioner.reserve_node.side_effect = reserved
self.assertRaises(exc.ReservationFailed, mi.reserve,
provisioner, instances, True)
provisioner.unprovision_node.assert_has_calls([
mock.call(1),
mock.call(2)
])

@mock.patch('metalsmith.sources.detect', autospec=True)
@mock.patch('metalsmith.instance_config.CloudInitConfig', autospec=True)
def test_provision(self, mock_config, mock_detect):
config = mock_config.return_value
image = mock_detect.return_value

provisioner = mock.Mock()
instances = [{
'name': 'node-1',
'hostname': 'overcloud-controller-1',
'image': {'href': 'overcloud-full'}
}, {
'name': 'node-2',
'hostname': 'overcloud-controller-2',
'image': {'href': 'overcloud-full'},
'nics': {'network': 'ctlplane'},
'root_size_gb': 200,
'swap_size_mb': 16,
'netboot': True,
'ssh_public_keys': 'abcd',
'user_name': 'centos',
'passwordless_sudo': False
}, {
'name': 'node-3',
'hostname': 'overcloud-controller-3',
'image': {'href': 'overcloud-full'}
}, {
'name': 'node-4',
'hostname': 'overcloud-compute-0',
'image': {'href': 'overcloud-full'}
}]
provisioned = [
mock.Mock(uuid=1),
mock.Mock(uuid=2),
mock.Mock(uuid=3),
mock.Mock(uuid=4),
]

# test provision success
provisioner.provision_node.side_effect = provisioned

# provision 4 nodes with concurrency of 2
result = mi.provision(provisioner, instances, 3600, 2, True, True)
provisioner.provision_node.assert_has_calls([
mock.call(
'node-1',
config=config,
hostname='overcloud-controller-1',
image=image,
netboot=False,
nics=None,
root_size_gb=None,
swap_size_mb=None
),
mock.call(
'node-2',
config=config,
hostname='overcloud-controller-2',
image=image,
netboot=True,
nics={'network': 'ctlplane'},
root_size_gb=200,
swap_size_mb=16
),
mock.call(
'node-3',
config=config,
hostname='overcloud-controller-3',
image=image,
netboot=False,
nics=None,
root_size_gb=None,
swap_size_mb=None
),
mock.call(
'node-4',
config=config,
hostname='overcloud-compute-0',
image=image,
netboot=False,
nics=None,
root_size_gb=None,
swap_size_mb=None
),
])
mock_config.assert_has_calls([
mock.call(ssh_keys=None),
mock.call(ssh_keys='abcd'),
])
config.add_user.assert_called_once_with(
'centos', admin=True, sudo=False)
mock_detect.assert_has_calls([
mock.call(
image='overcloud-full',
checksum=None,
kernel=None,
ramdisk=None
),
mock.call(
image='overcloud-full',
checksum=None,
kernel=None,
ramdisk=None
),
mock.call(
image='overcloud-full',
checksum=None,
kernel=None,
ramdisk=None
),
mock.call(
image='overcloud-full',
checksum=None,
kernel=None,
ramdisk=None
),
])
self.assertTrue(result[0])
self.assertEqual(provisioned, result[1])

# test provision failure with cleanup
instances = [{
'name': 'node-1',
'hostname': 'overcloud-controller-1',
'image': {'href': 'overcloud-full'}
}, {
'name': 'node-2',
'hostname': 'overcloud-controller-2',
'image': {'href': 'overcloud-full'},
}, {
'name': 'node-3',
'hostname': 'overcloud-controller-3',
'image': {'href': 'overcloud-full'},
}]
provisioned = [
mock.Mock(uuid=1),
mock.Mock(uuid=2),
exc.Error('ouch')
]
provisioner.provision_node.side_effect = provisioned
self.assertRaises(exc.Error, mi.provision,
provisioner, instances, 3600, 20, True, True)
provisioner.unprovision_node.assert_has_calls([
mock.call(1),
mock.call(2)
])

0 comments on commit 62b8b1d

Please sign in to comment.