summaryrefslogtreecommitdiff
path: root/ironic_python_agent/tests
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-04-09 09:31:49 +0000
committerGerrit Code Review <review@openstack.org>2020-04-09 09:31:49 +0000
commitb9e320e76fbed100502d29d3b1d6f0586f1b873f (patch)
treebea69ad9e872abefdaa7da838877b5148543f9fc /ironic_python_agent/tests
parentbdc5e9448decaa8e4ebc9e1d6b62508cba967ad4 (diff)
parent1b4ce47921b6a09fbf2894b021217a87d82fe7aa (diff)
downloadironic-python-agent-b9e320e76fbed100502d29d3b1d6f0586f1b873f.tar.gz
Merge "Add an ability to run in-band deploy steps"
Diffstat (limited to 'ironic_python_agent/tests')
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_clean.py37
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_deploy.py241
-rw-r--r--ironic_python_agent/tests/unit/test_hardware.py21
3 files changed, 270 insertions, 29 deletions
diff --git a/ironic_python_agent/tests/unit/extensions/test_clean.py b/ironic_python_agent/tests/unit/extensions/test_clean.py
index b78d347c..43cd8ec9 100644
--- a/ironic_python_agent/tests/unit/extensions/test_clean.py
+++ b/ironic_python_agent/tests/unit/extensions/test_clean.py
@@ -34,8 +34,8 @@ class TestCleanExtension(base.IronicAgentTest):
}
self.version = {'generic': '1', 'specific': '1'}
- @mock.patch('ironic_python_agent.extensions.clean.'
- '_get_current_clean_version', autospec=True)
+ @mock.patch('ironic_python_agent.hardware.get_current_versions',
+ autospec=True)
@mock.patch('ironic_python_agent.hardware.dispatch_to_all_managers',
autospec=True)
def test_get_clean_steps(self, mock_dispatch, mock_version,
@@ -141,7 +141,7 @@ class TestCleanExtension(base.IronicAgentTest):
@mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
autospec=True)
- @mock.patch('ironic_python_agent.extensions.clean._check_clean_version',
+ @mock.patch('ironic_python_agent.hardware.check_versions',
autospec=True)
def test_execute_clean_step(self, mock_version, mock_dispatch,
mock_cache_node):
@@ -167,7 +167,7 @@ class TestCleanExtension(base.IronicAgentTest):
@mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
autospec=True)
- @mock.patch('ironic_python_agent.extensions.clean._check_clean_version',
+ @mock.patch('ironic_python_agent.hardware.check_versions',
autospec=True)
def test_execute_clean_step_tuple_result(self, mock_version,
mock_dispatch, mock_cache_node):
@@ -191,7 +191,7 @@ class TestCleanExtension(base.IronicAgentTest):
self.assertEqual(expected_result, async_result.command_result)
mock_cache_node.assert_called_once_with(self.node)
- @mock.patch('ironic_python_agent.extensions.clean._check_clean_version',
+ @mock.patch('ironic_python_agent.hardware.check_versions',
autospec=True)
def test_execute_clean_step_no_step(self, mock_version, mock_cache_node):
async_result = self.agent_extension.execute_clean_step(
@@ -205,7 +205,7 @@ class TestCleanExtension(base.IronicAgentTest):
@mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
autospec=True)
- @mock.patch('ironic_python_agent.extensions.clean._check_clean_version',
+ @mock.patch('ironic_python_agent.hardware.check_versions',
autospec=True)
def test_execute_clean_step_fail(self, mock_version, mock_dispatch,
mock_cache_node):
@@ -226,12 +226,12 @@ class TestCleanExtension(base.IronicAgentTest):
@mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
autospec=True)
- @mock.patch('ironic_python_agent.extensions.clean._check_clean_version',
+ @mock.patch('ironic_python_agent.hardware.check_versions',
autospec=True)
def test_execute_clean_step_version_mismatch(self, mock_version,
mock_dispatch,
mock_cache_node):
- mock_version.side_effect = errors.CleanVersionMismatch(
+ mock_version.side_effect = errors.VersionMismatch(
{'GenericHardwareManager': 1}, {'GenericHardwareManager': 2})
async_result = self.agent_extension.execute_clean_step(
@@ -241,24 +241,3 @@ class TestCleanExtension(base.IronicAgentTest):
self.assertEqual('CLEAN_VERSION_MISMATCH', async_result.command_status)
mock_version.assert_called_once_with(self.version)
-
-
-@mock.patch('ironic_python_agent.hardware.dispatch_to_all_managers',
- autospec=True)
-class TestCleanVersion(base.IronicAgentTest):
- version = {'generic': '1', 'specific': '1'}
-
- def test__get_current_clean_version(self, mock_dispatch):
- mock_dispatch.return_value = {'SpecificHardwareManager':
- {'name': 'specific', 'version': '1'},
- 'GenericHardwareManager':
- {'name': 'generic', 'version': '1'}}
- self.assertEqual(self.version, clean._get_current_clean_version())
-
- def test__check_clean_version_fail(self, mock_dispatch):
- mock_dispatch.return_value = {'SpecificHardwareManager':
- {'name': 'specific', 'version': '1'}}
-
- self.assertRaises(errors.CleanVersionMismatch,
- clean._check_clean_version,
- {'not_specific': '1'})
diff --git a/ironic_python_agent/tests/unit/extensions/test_deploy.py b/ironic_python_agent/tests/unit/extensions/test_deploy.py
new file mode 100644
index 00000000..531545f1
--- /dev/null
+++ b/ironic_python_agent/tests/unit/extensions/test_deploy.py
@@ -0,0 +1,241 @@
+# 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 mock
+
+from ironic_python_agent import errors
+from ironic_python_agent.extensions import deploy
+from ironic_python_agent.tests.unit import base
+
+
+@mock.patch('ironic_python_agent.hardware.cache_node', autospec=True)
+class TestDeployExtension(base.IronicAgentTest):
+ def setUp(self):
+ super(TestDeployExtension, self).setUp()
+ self.agent_extension = deploy.DeployExtension()
+ self.node = {'uuid': 'dda135fb-732d-4742-8e72-df8f3199d244'}
+ self.ports = []
+ self.step = {
+ 'GenericHardwareManager':
+ [{'step': 'erase_devices',
+ 'priority': 10,
+ 'interface': 'deploy'}]
+ }
+ self.version = {'generic': '1', 'specific': '1'}
+
+ @mock.patch('ironic_python_agent.hardware.get_current_versions',
+ autospec=True)
+ @mock.patch('ironic_python_agent.hardware.dispatch_to_all_managers',
+ autospec=True)
+ def test_get_deploy_steps(self, mock_dispatch, mock_version,
+ mock_cache_node):
+ mock_version.return_value = self.version
+
+ manager_steps = {
+ 'SpecificHardwareManager': [
+ {
+ 'step': 'erase_devices',
+ 'priority': 10,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ {
+ 'step': 'upgrade_bios',
+ 'priority': 20,
+ 'interface': 'deploy',
+ 'reboot_requested': True
+ },
+ {
+ 'step': 'upgrade_firmware',
+ 'priority': 60,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ ],
+ 'FirmwareHardwareManager': [
+ {
+ 'step': 'upgrade_firmware',
+ 'priority': 10,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ {
+ 'step': 'erase_devices',
+ 'priority': 40,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ ],
+ 'DiskHardwareManager': [
+ {
+ 'step': 'erase_devices',
+ 'priority': 50,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ ]
+ }
+
+ expected_steps = {
+ 'SpecificHardwareManager': [
+ # Only manager upgrading BIOS
+ {
+ 'step': 'upgrade_bios',
+ 'priority': 20,
+ 'interface': 'deploy',
+ 'reboot_requested': True
+ }
+ ],
+ 'FirmwareHardwareManager': [
+ # Higher support than specific, even though lower priority
+ {
+ 'step': 'upgrade_firmware',
+ 'priority': 10,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ ],
+ 'DiskHardwareManager': [
+ # Higher support than specific, higher priority than firmware
+ {
+ 'step': 'erase_devices',
+ 'priority': 50,
+ 'interface': 'deploy',
+ 'reboot_requested': False
+ },
+ ]
+
+ }
+
+ hardware_support = {
+ 'SpecificHardwareManager': 3,
+ 'FirmwareHardwareManager': 4,
+ 'DiskHardwareManager': 4
+ }
+
+ mock_dispatch.side_effect = [manager_steps, hardware_support]
+ expected_return = {
+ 'hardware_manager_version': self.version,
+ 'deploy_steps': expected_steps
+ }
+
+ async_results = self.agent_extension.get_deploy_steps(node=self.node,
+ ports=self.ports)
+
+ # Ordering of the deploy steps doesn't matter; they're sorted by
+ # 'priority' in Ironic
+ self.assertEqual(expected_return,
+ async_results.join().command_result)
+ mock_cache_node.assert_called_once_with(self.node)
+
+ @mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
+ autospec=True)
+ @mock.patch('ironic_python_agent.hardware.check_versions',
+ autospec=True)
+ def test_execute_deploy_step(self, mock_version, mock_dispatch,
+ mock_cache_node):
+ result = 'deployed'
+ mock_dispatch.return_value = result
+
+ expected_result = {
+ 'deploy_step': self.step['GenericHardwareManager'][0],
+ 'deploy_result': result
+ }
+ async_result = self.agent_extension.execute_deploy_step(
+ step=self.step['GenericHardwareManager'][0],
+ node=self.node, ports=self.ports,
+ deploy_version=self.version)
+ async_result.join()
+
+ mock_version.assert_called_once_with(self.version)
+ mock_dispatch.assert_called_once_with(
+ self.step['GenericHardwareManager'][0]['step'],
+ self.node, self.ports)
+ self.assertEqual(expected_result, async_result.command_result)
+ mock_cache_node.assert_called_once_with(self.node)
+
+ @mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
+ autospec=True)
+ @mock.patch('ironic_python_agent.hardware.check_versions',
+ autospec=True)
+ def test_execute_deploy_step_tuple_result(self, mock_version,
+ mock_dispatch, mock_cache_node):
+ result = ('stdout', 'stderr')
+ mock_dispatch.return_value = result
+
+ expected_result = {
+ 'deploy_step': self.step['GenericHardwareManager'][0],
+ 'deploy_result': ['stdout', 'stderr']
+ }
+ async_result = self.agent_extension.execute_deploy_step(
+ step=self.step['GenericHardwareManager'][0],
+ node=self.node, ports=self.ports,
+ deploy_version=self.version)
+ async_result.join()
+
+ mock_version.assert_called_once_with(self.version)
+ mock_dispatch.assert_called_once_with(
+ self.step['GenericHardwareManager'][0]['step'],
+ self.node, self.ports)
+ self.assertEqual(expected_result, async_result.command_result)
+ mock_cache_node.assert_called_once_with(self.node)
+
+ @mock.patch('ironic_python_agent.hardware.check_versions',
+ autospec=True)
+ def test_execute_deploy_step_no_step(self, mock_version, mock_cache_node):
+ async_result = self.agent_extension.execute_deploy_step(
+ step={}, node=self.node, ports=self.ports,
+ deploy_version=self.version)
+ async_result.join()
+
+ self.assertEqual('FAILED', async_result.command_status)
+ mock_version.assert_called_once_with(self.version)
+ mock_cache_node.assert_called_once_with(self.node)
+
+ @mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
+ autospec=True)
+ @mock.patch('ironic_python_agent.hardware.check_versions',
+ autospec=True)
+ def test_execute_deploy_step_fail(self, mock_version, mock_dispatch,
+ mock_cache_node):
+ mock_dispatch.side_effect = RuntimeError
+
+ async_result = self.agent_extension.execute_deploy_step(
+ step=self.step['GenericHardwareManager'][0], node=self.node,
+ ports=self.ports, deploy_version=self.version)
+ async_result.join()
+
+ self.assertEqual('FAILED', async_result.command_status)
+
+ mock_version.assert_called_once_with(self.version)
+ mock_dispatch.assert_called_once_with(
+ self.step['GenericHardwareManager'][0]['step'],
+ self.node, self.ports)
+ mock_cache_node.assert_called_once_with(self.node)
+
+ @mock.patch('ironic_python_agent.hardware.dispatch_to_managers',
+ autospec=True)
+ @mock.patch('ironic_python_agent.hardware.check_versions',
+ autospec=True)
+ def test_execute_deploy_step_version_mismatch(self, mock_version,
+ mock_dispatch,
+ mock_cache_node):
+ mock_version.side_effect = errors.VersionMismatch(
+ {'GenericHardwareManager': 1}, {'GenericHardwareManager': 2})
+
+ async_result = self.agent_extension.execute_deploy_step(
+ step=self.step['GenericHardwareManager'][0], node=self.node,
+ ports=self.ports, deploy_version=self.version)
+ async_result.join()
+ self.assertEqual('CLEAN_VERSION_MISMATCH', async_result.command_status)
+
+ mock_version.assert_called_once_with(self.version)
diff --git a/ironic_python_agent/tests/unit/test_hardware.py b/ironic_python_agent/tests/unit/test_hardware.py
index 7f98559a..173c51ba 100644
--- a/ironic_python_agent/tests/unit/test_hardware.py
+++ b/ironic_python_agent/tests/unit/test_hardware.py
@@ -4336,3 +4336,24 @@ def create_hdparm_info(supported=False, enabled=False, locked=False,
update_values(values, enhanced_erase, 'enhanced_erase')
return HDPARM_INFO_TEMPLATE % values
+
+
+@mock.patch('ironic_python_agent.hardware.dispatch_to_all_managers',
+ autospec=True)
+class TestVersions(base.IronicAgentTest):
+ version = {'generic': '1', 'specific': '1'}
+
+ def test_get_current_versions(self, mock_dispatch):
+ mock_dispatch.return_value = {'SpecificHardwareManager':
+ {'name': 'specific', 'version': '1'},
+ 'GenericHardwareManager':
+ {'name': 'generic', 'version': '1'}}
+ self.assertEqual(self.version, hardware.get_current_versions())
+
+ def test_check_versions(self, mock_dispatch):
+ mock_dispatch.return_value = {'SpecificHardwareManager':
+ {'name': 'specific', 'version': '1'}}
+
+ self.assertRaises(errors.VersionMismatch,
+ hardware.check_versions,
+ {'not_specific': '1'})