diff options
author | Mathieu Gagné <mgagne@iweb.com> | 2017-09-07 10:34:45 -0400 |
---|---|---|
committer | Mathieu Gagné <mgagne@iweb.com> | 2017-10-19 13:07:03 -0400 |
commit | 6a8b38a2caafe89ebd73fda8c72b8f4fbbdc9f6b (patch) | |
tree | 1b988ed2f50848a399957f6c60a3fac6f11d4d0f /ironic/tests/unit/api | |
parent | 7a2f3482d0156ef48bcb19c74644f4bca2562546 (diff) | |
download | ironic-6a8b38a2caafe89ebd73fda8c72b8f4fbbdc9f6b.tar.gz |
Add ability to provide configdrive when rebuilding
Previously, the configdrive could only be set when setting
the node's provisioning state to "active". When rebuilding,
the old configdrive was used and therefore was never updated
with latest content.
This change introduces the API microversion 1.35 which will allow
configdrive to be provided when setting the node's provisioning state
to "rebuild".
Closes-bug: #1575935
Change-Id: I9a5529f9fa796c75621e9f4354886bf3032cc248
Diffstat (limited to 'ironic/tests/unit/api')
-rw-r--r-- | ironic/tests/unit/api/controllers/v1/test_node.py | 80 | ||||
-rw-r--r-- | ironic/tests/unit/api/controllers/v1/test_utils.py | 25 |
2 files changed, 97 insertions, 8 deletions
diff --git a/ironic/tests/unit/api/controllers/v1/test_node.py b/ironic/tests/unit/api/controllers/v1/test_node.py index 84d6c1c4f..79e46dc4d 100644 --- a/ironic/tests/unit/api/controllers/v1/test_node.py +++ b/ironic/tests/unit/api/controllers/v1/test_node.py @@ -2966,8 +2966,11 @@ class TestPut(test_api_base.BaseApiTest): {'target': states.ACTIVE}) self.assertEqual(http_client.ACCEPTED, ret.status_code) self.assertEqual(b'', ret.body) - self.mock_dnd.assert_called_once_with( - mock.ANY, self.node.uuid, False, None, 'test-topic') + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=False, + configdrive=None, + topic='test-topic') # Check location header self.assertIsNotNone(ret.location) expected_location = '/v1/nodes/%s/states' % self.node.uuid @@ -2986,16 +2989,74 @@ class TestPut(test_api_base.BaseApiTest): headers={api_base.Version.string: "1.5"}) self.assertEqual(http_client.ACCEPTED, ret.status_code) self.assertEqual(b'', ret.body) - self.mock_dnd.assert_called_once_with( - mock.ANY, self.node.uuid, False, None, 'test-topic') + + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=False, + configdrive=None, + topic='test-topic') def test_provision_with_deploy_configdrive(self): ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid, {'target': states.ACTIVE, 'configdrive': 'foo'}) self.assertEqual(http_client.ACCEPTED, ret.status_code) self.assertEqual(b'', ret.body) - self.mock_dnd.assert_called_once_with( - mock.ANY, self.node.uuid, False, 'foo', 'test-topic') + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=False, + configdrive='foo', + topic='test-topic') + # Check location header + self.assertIsNotNone(ret.location) + expected_location = '/v1/nodes/%s/states' % self.node.uuid + self.assertEqual(urlparse.urlparse(ret.location).path, + expected_location) + + def test_provision_with_rebuild(self): + node = self.node + node.provision_state = states.ACTIVE + node.target_provision_state = states.NOSTATE + node.save() + ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid, + {'target': states.REBUILD}) + self.assertEqual(http_client.ACCEPTED, ret.status_code) + self.assertEqual(b'', ret.body) + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=True, + configdrive=None, + topic='test-topic') + # Check location header + self.assertIsNotNone(ret.location) + expected_location = '/v1/nodes/%s/states' % self.node.uuid + self.assertEqual(urlparse.urlparse(ret.location).path, + expected_location) + + def test_provision_with_rebuild_unsupported_configdrive(self): + node = self.node + node.provision_state = states.ACTIVE + node.target_provision_state = states.NOSTATE + node.save() + ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid, + {'target': states.REBUILD, 'configdrive': 'foo'}, + expect_errors=True) + self.assertEqual(http_client.BAD_REQUEST, ret.status_code) + + def test_provision_with_rebuild_configdrive(self): + node = self.node + node.provision_state = states.ACTIVE + node.target_provision_state = states.NOSTATE + node.save() + ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid, + {'target': states.REBUILD, 'configdrive': 'foo'}, + headers={api_base.Version.string: '1.35'}) + self.assertEqual(http_client.ACCEPTED, ret.status_code) + self.assertEqual(b'', ret.body) + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=True, + configdrive='foo', + topic='test-topic') # Check location header self.assertIsNotNone(ret.location) expected_location = '/v1/nodes/%s/states' % self.node.uuid @@ -3081,8 +3142,11 @@ class TestPut(test_api_base.BaseApiTest): {'target': states.ACTIVE}) self.assertEqual(http_client.ACCEPTED, ret.status_code) self.assertEqual(b'', ret.body) - self.mock_dnd.assert_called_once_with( - mock.ANY, node.uuid, False, None, 'test-topic') + self.mock_dnd.assert_called_once_with(context=mock.ANY, + node_id=self.node.uuid, + rebuild=False, + configdrive=None, + topic='test-topic') # Check location header self.assertIsNotNone(ret.location) expected_location = '/v1/nodes/%s/states' % node.uuid diff --git a/ironic/tests/unit/api/controllers/v1/test_utils.py b/ironic/tests/unit/api/controllers/v1/test_utils.py index 4ffb02556..54f038da4 100644 --- a/ironic/tests/unit/api/controllers/v1/test_utils.py +++ b/ironic/tests/unit/api/controllers/v1/test_utils.py @@ -25,6 +25,7 @@ import wsme from ironic.api.controllers.v1 import node as api_node from ironic.api.controllers.v1 import utils from ironic.common import exception +from ironic.common import states from ironic import objects from ironic.tests import base from ironic.tests.unit.api import utils as test_api_utils @@ -444,6 +445,30 @@ class TestApiUtils(base.TestCase): mock_request.version.minor = 33 self.assertFalse(utils.allow_port_physical_network()) + @mock.patch.object(pecan, 'request', spec_set=['version']) + def test_allow_node_rebuild_with_configdrive(self, mock_request): + mock_request.version.minor = 35 + self.assertTrue(utils.allow_node_rebuild_with_configdrive()) + mock_request.version.minor = 34 + self.assertFalse(utils.allow_node_rebuild_with_configdrive()) + + @mock.patch.object(pecan, 'request', spec_set=['version']) + def test_check_allow_configdrive_fails(self, mock_request): + mock_request.version.minor = 35 + self.assertRaises(wsme.exc.ClientSideError, + utils.check_allow_configdrive, states.DELETED) + mock_request.version.minor = 34 + self.assertRaises(wsme.exc.ClientSideError, + utils.check_allow_configdrive, states.REBUILD) + + @mock.patch.object(pecan, 'request', spec_set=['version']) + def test_check_allow_configdrive(self, mock_request): + mock_request.version.minor = 35 + utils.check_allow_configdrive(states.ACTIVE) + utils.check_allow_configdrive(states.REBUILD) + mock_request.version.minor = 34 + utils.check_allow_configdrive(states.ACTIVE) + class TestNodeIdent(base.TestCase): |