Support /v1/shards
Unit Tests Boilerplate was generated by GPT-4o Generated-By: GPT-4o Change-Id: I6f45cc678a5931e3525fb85256c1608e75fe089f
This commit is contained in:
parent
2c189bc457
commit
f2bed8f253
36
ironicclient/osc/v1/baremetal_shard.py
Normal file
36
ironicclient/osc/v1/baremetal_shard.py
Normal file
@ -0,0 +1,36 @@
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils as oscutils
|
||||
|
||||
from ironicclient.v1 import resource_fields as res_fields
|
||||
|
||||
|
||||
class ListBaremetalShard(command.Lister):
|
||||
"""List baremetal shards."""
|
||||
|
||||
log = logging.getLogger(__name__ + ".ListBaremetalShard")
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)", parsed_args)
|
||||
client = self.app.client_manager.baremetal
|
||||
|
||||
data = client.shard.list()
|
||||
columns = res_fields.SHARD_RESOURCE.fields
|
||||
labels = res_fields.SHARD_RESOURCE.labels
|
||||
|
||||
return (labels,
|
||||
(oscutils.get_item_properties(s, columns) for s in data))
|
@ -255,6 +255,14 @@ RUNBOOK = {
|
||||
'steps': baremetal_runbook_steps,
|
||||
'extra': baremetal_runbook_extra,
|
||||
}
|
||||
|
||||
baremetal_shard_name = 'example_shard'
|
||||
baremetal_shard_count = 47
|
||||
SHARD = {
|
||||
'name': baremetal_shard_name,
|
||||
'count': baremetal_shard_count,
|
||||
}
|
||||
|
||||
NODE_HISTORY = [
|
||||
{
|
||||
'uuid': 'abcdef1',
|
||||
|
57
ironicclient/tests/unit/osc/v1/test_baremetal_shard.py
Normal file
57
ironicclient/tests/unit/osc/v1/test_baremetal_shard.py
Normal file
@ -0,0 +1,57 @@
|
||||
# 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 copy
|
||||
|
||||
from ironicclient.osc.v1 import baremetal_shard
|
||||
from ironicclient.tests.unit.osc.v1 import fakes as baremetal_fakes
|
||||
|
||||
|
||||
class TestBaremetalShard(baremetal_fakes.TestBaremetal):
|
||||
def setUp(self):
|
||||
super(TestBaremetalShard, self).setUp()
|
||||
self.baremetal_mock = self.app.client_manager.baremetal
|
||||
self.baremetal_mock.reset_mock()
|
||||
|
||||
|
||||
class TestBaremetalShardList(TestBaremetalShard):
|
||||
def setUp(self):
|
||||
super(TestBaremetalShardList, self).setUp()
|
||||
|
||||
# Return a list containing mocked shard data to
|
||||
# simulate the expected output
|
||||
self.baremetal_mock.shard.list.return_value = [
|
||||
baremetal_fakes.FakeBaremetalResource(
|
||||
None,
|
||||
copy.deepcopy(baremetal_fakes.SHARD),
|
||||
loaded=True,
|
||||
),
|
||||
]
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = baremetal_shard.ListBaremetalShard(self.app, None)
|
||||
|
||||
def test_shard_list(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
# Parse arguments and invoke command
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
# Define expected columns and data output
|
||||
collist = ("Name", "Count")
|
||||
datalist = ((baremetal_fakes.baremetal_shard_name,
|
||||
baremetal_fakes.baremetal_shard_count), )
|
||||
|
||||
self.assertEqual(collist, columns)
|
||||
self.assertEqual(datalist, tuple(data))
|
115
ironicclient/tests/unit/v1/test_shard.py
Normal file
115
ironicclient/tests/unit/v1/test_shard.py
Normal file
@ -0,0 +1,115 @@
|
||||
# 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.mock import patch
|
||||
|
||||
from ironicclient.v1.shard import ShardManager
|
||||
|
||||
|
||||
class TestShardManager(unittest.TestCase):
|
||||
|
||||
@patch('ironicclient.common.base.Manager._list')
|
||||
def test_list_shards(self, mock_list):
|
||||
# Mock response for the list of shards
|
||||
mock_response = [
|
||||
{'name': 'example_shard1', 'count': 47},
|
||||
{'name': 'example_shard2', 'count': 46},
|
||||
{'name': None, 'count': 3} # Nodes with no shard assigned
|
||||
]
|
||||
|
||||
# Configure mock to return the mocked response
|
||||
mock_list.return_value = mock_response
|
||||
|
||||
# Initialize the ShardManager
|
||||
shard_manager = ShardManager(api=None) # `api=None` for simplicity
|
||||
|
||||
# Perform the test call
|
||||
result = shard_manager.list(os_ironic_api_version="1.82")
|
||||
|
||||
# Assertions
|
||||
mock_list.assert_called_once_with(
|
||||
shard_manager._path(None),
|
||||
"shards",
|
||||
os_ironic_api_version="1.82",
|
||||
global_request_id=None
|
||||
)
|
||||
self.assertEqual(len(result), 3)
|
||||
self.assertEqual(result[0]['name'], 'example_shard1')
|
||||
self.assertEqual(result[0]['count'], 47)
|
||||
self.assertEqual(result[1]['name'], 'example_shard2')
|
||||
self.assertEqual(result[1]['count'], 46)
|
||||
self.assertIsNone(result[2]['name'])
|
||||
self.assertEqual(result[2]['count'], 3)
|
||||
|
||||
@patch('ironicclient.common.base.Manager._list')
|
||||
def test_list_shards_empty(self, mock_list):
|
||||
# Test when the shards list is empty
|
||||
mock_list.return_value = []
|
||||
|
||||
# Initialize the ShardManager
|
||||
shard_manager = ShardManager(api=None)
|
||||
|
||||
# Perform the test call
|
||||
result = shard_manager.list(os_ironic_api_version="1.82")
|
||||
|
||||
# Assertions
|
||||
mock_list.assert_called_once_with(
|
||||
shard_manager._path(None),
|
||||
"shards",
|
||||
os_ironic_api_version="1.82",
|
||||
global_request_id=None
|
||||
)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
@patch('ironicclient.common.base.Manager._list')
|
||||
def test_list_shards_with_global_request_id(self, mock_list):
|
||||
# Test with global request ID
|
||||
mock_response = [
|
||||
{'name': 'example_shard1', 'count': 47},
|
||||
{'name': 'example_shard2', 'count': 46}
|
||||
]
|
||||
mock_list.return_value = mock_response
|
||||
|
||||
# Initialize the ShardManager
|
||||
shard_manager = ShardManager(api=None)
|
||||
|
||||
# Perform the test call with global_request_id
|
||||
result = shard_manager.list(
|
||||
os_ironic_api_version="1.82",
|
||||
global_request_id="req-12345"
|
||||
)
|
||||
|
||||
# Assertions
|
||||
mock_list.assert_called_once_with(
|
||||
shard_manager._path(None),
|
||||
"shards",
|
||||
os_ironic_api_version="1.82",
|
||||
global_request_id="req-12345"
|
||||
)
|
||||
self.assertEqual(result, mock_response)
|
||||
|
||||
@patch('ironicclient.common.base.Manager._list')
|
||||
def test_list_shards_api_version_mismatch(self, mock_list):
|
||||
# Simulate a 404 error for an unsupported API version
|
||||
mock_list.side_effect = ValueError(
|
||||
"404 Not Found: The requested version is not supported"
|
||||
)
|
||||
|
||||
# Initialize the ShardManager
|
||||
shard_manager = ShardManager(api=None)
|
||||
|
||||
# Perform the test call and assert exception is raised
|
||||
with self.assertRaises(ValueError) as context:
|
||||
shard_manager.list(os_ironic_api_version="1.50")
|
||||
|
||||
self.assertIn("404 Not Found", str(context.exception))
|
@ -28,6 +28,7 @@ from ironicclient.v1 import node
|
||||
from ironicclient.v1 import port
|
||||
from ironicclient.v1 import portgroup
|
||||
from ironicclient.v1 import runbook
|
||||
from ironicclient.v1 import shard
|
||||
from ironicclient.v1 import volume_connector
|
||||
from ironicclient.v1 import volume_target
|
||||
|
||||
@ -106,6 +107,7 @@ class Client(object):
|
||||
self.allocation = allocation.AllocationManager(self.http_client)
|
||||
self.deploy_template = deploy_template.DeployTemplateManager(
|
||||
self.http_client)
|
||||
self.shard = shard.ShardManager(self.http_client)
|
||||
|
||||
@property
|
||||
def current_api_version(self):
|
||||
|
@ -47,6 +47,7 @@ class Resource(object):
|
||||
'conductor': 'Conductor',
|
||||
'conductor_group': 'Conductor Group',
|
||||
'console_enabled': 'Console Enabled',
|
||||
'count': 'Count',
|
||||
'created_at': 'Created At',
|
||||
'default_bios_interface': 'Default BIOS Interface',
|
||||
'default_boot_interface': 'Default Boot Interface',
|
||||
@ -643,3 +644,8 @@ NODE_HISTORY_DETAILED_RESOURCE = Resource(
|
||||
'conductor',
|
||||
'user']
|
||||
)
|
||||
|
||||
SHARD_RESOURCE = Resource(
|
||||
['name',
|
||||
'count']
|
||||
)
|
||||
|
39
ironicclient/v1/shard.py
Normal file
39
ironicclient/v1/shard.py
Normal file
@ -0,0 +1,39 @@
|
||||
# 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 ironicclient.common import base
|
||||
|
||||
|
||||
class Shard(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<Shard %s>" % self._info
|
||||
|
||||
|
||||
class ShardManager(base.Manager):
|
||||
resource_class = Shard
|
||||
_resource_name = 'shards'
|
||||
|
||||
def list(self, os_ironic_api_version=None, global_request_id=None):
|
||||
"""Retrieve a list of shards.
|
||||
|
||||
:param os_ironic_api_version: String version (e.g. "1.35") to use for
|
||||
the request. If not specified, the client's default is used.
|
||||
|
||||
:param global_request_id: String containing global request ID header
|
||||
value (in form "req-<UUID>") to use for the request.
|
||||
|
||||
:returns: A list of conductors.
|
||||
|
||||
"""
|
||||
header_values = {"os_ironic_api_version": os_ironic_api_version,
|
||||
"global_request_id": global_request_id}
|
||||
return self._list(self._path(None), "shards", **header_values)
|
@ -118,6 +118,7 @@ openstack.baremetal.v1 =
|
||||
baremetal_port_group_set = ironicclient.osc.v1.baremetal_portgroup:SetBaremetalPortGroup
|
||||
baremetal_port_group_show = ironicclient.osc.v1.baremetal_portgroup:ShowBaremetalPortGroup
|
||||
baremetal_port_group_unset = ironicclient.osc.v1.baremetal_portgroup:UnsetBaremetalPortGroup
|
||||
baremetal_shard_list = ironicclient.osc.v1.baremetal_shard:ListBaremetalShard
|
||||
baremetal_volume_connector_create = ironicclient.osc.v1.baremetal_volume_connector:CreateBaremetalVolumeConnector
|
||||
baremetal_volume_connector_delete = ironicclient.osc.v1.baremetal_volume_connector:DeleteBaremetalVolumeConnector
|
||||
baremetal_volume_connector_list = ironicclient.osc.v1.baremetal_volume_connector:ListBaremetalVolumeConnector
|
||||
|
Loading…
Reference in New Issue
Block a user