Skip to content

Commit 8417444

Browse files
committed
Refactor "os availability zone list"
Refactor the "os availability zone list" command to make it a common command instead of a compute-only command. Since availability zones are common to compute, volume and network (new), this refactoring allows availability zone support to be added for volume and network. In addition to the refactor, unit and functional tests were added. Change-Id: I63e9d41d229b21cd38e5a083493042c096d65e05 Partial-Bug: #1532945
1 parent 9317df0 commit 8417444

5 files changed

Lines changed: 201 additions & 2 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from functional.common import test
14+
15+
16+
class AvailabilityZoneTests(test.TestCase):
17+
"""Functional tests for availability zone. """
18+
HEADERS = ["'Zone Name'"]
19+
# So far, all components have the same default availability zone name.
20+
DEFAULT_AZ_NAME = 'nova'
21+
22+
def test_availability_zone_list(self):
23+
opts = self.get_list_opts(self.HEADERS)
24+
raw_output = self.openstack('availability zone list' + opts)
25+
self.assertIn(self.DEFAULT_AZ_NAME, raw_output)
File renamed without changes.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
import six
15+
16+
from openstackclient.common import availability_zone
17+
from openstackclient.tests.compute.v2 import fakes as compute_fakes
18+
from openstackclient.tests import fakes
19+
from openstackclient.tests import utils
20+
21+
22+
def _build_compute_az_datalist(compute_az, long_datalist=False):
23+
datalist = ()
24+
if not long_datalist:
25+
datalist = (
26+
compute_az.zoneName,
27+
'available',
28+
)
29+
else:
30+
for host, services in six.iteritems(compute_az.hosts):
31+
for service, state in six.iteritems(services):
32+
datalist += (
33+
compute_az.zoneName,
34+
'available',
35+
host,
36+
service,
37+
'enabled :-) ' + state['updated_at'],
38+
)
39+
return (datalist,)
40+
41+
42+
class TestAvailabilityZone(utils.TestCommand):
43+
44+
def setUp(self):
45+
super(TestAvailabilityZone, self).setUp()
46+
47+
compute_client = compute_fakes.FakeComputev2Client(
48+
endpoint=fakes.AUTH_URL,
49+
token=fakes.AUTH_TOKEN,
50+
)
51+
self.app.client_manager.compute = compute_client
52+
53+
self.compute_azs_mock = compute_client.availability_zones
54+
self.compute_azs_mock.reset_mock()
55+
56+
57+
class TestAvailabilityZoneList(TestAvailabilityZone):
58+
59+
compute_azs = \
60+
compute_fakes.FakeAvailabilityZone.create_availability_zones()
61+
62+
def setUp(self):
63+
super(TestAvailabilityZoneList, self).setUp()
64+
65+
self.compute_azs_mock.list.return_value = self.compute_azs
66+
67+
# Get the command object to test
68+
self.cmd = availability_zone.ListAvailabilityZone(self.app, None)
69+
70+
def test_availability_zone_list_no_options(self):
71+
arglist = []
72+
verifylist = []
73+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
74+
75+
# DisplayCommandBase.take_action() returns two tuples
76+
columns, data = self.cmd.take_action(parsed_args)
77+
78+
self.compute_azs_mock.list.assert_called_with()
79+
80+
columnslist = ('Zone Name', 'Zone Status')
81+
self.assertEqual(columnslist, columns)
82+
datalist = ()
83+
for compute_az in self.compute_azs:
84+
datalist += _build_compute_az_datalist(compute_az)
85+
self.assertEqual(datalist, tuple(data))
86+
87+
def test_availability_zone_list_long(self):
88+
arglist = [
89+
'--long',
90+
]
91+
verifylist = [
92+
('long', True),
93+
]
94+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
95+
96+
# DisplayCommandBase.take_action() returns two tuples
97+
columns, data = self.cmd.take_action(parsed_args)
98+
99+
self.compute_azs_mock.list.assert_called_with()
100+
101+
columnslist = (
102+
'Zone Name',
103+
'Zone Status',
104+
'Host Name',
105+
'Service Name',
106+
'Service Status',
107+
)
108+
self.assertEqual(columnslist, columns)
109+
datalist = ()
110+
for compute_az in self.compute_azs:
111+
datalist += _build_compute_az_datalist(compute_az,
112+
long_datalist=True)
113+
self.assertEqual(datalist, tuple(data))

openstackclient/tests/compute/v2/fakes.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@
8888

8989
class FakeComputev2Client(object):
9090
def __init__(self, **kwargs):
91+
self.availability_zones = mock.Mock()
92+
self.availability_zones.resource_class = fakes.FakeResource(None, {})
9193
self.images = mock.Mock()
9294
self.images.resource_class = fakes.FakeResource(None, {})
9395
self.servers = mock.Mock()
@@ -289,3 +291,63 @@ def get_flavors(flavors=None, count=2):
289291
if flavors is None:
290292
flavors = FakeServer.create_flavors(count)
291293
return mock.MagicMock(side_effect=flavors)
294+
295+
296+
class FakeAvailabilityZone(object):
297+
"""Fake one or more compute availability zones (AZs)."""
298+
299+
@staticmethod
300+
def create_one_availability_zone(attrs={}, methods={}):
301+
"""Create a fake AZ.
302+
303+
:param Dictionary attrs:
304+
A dictionary with all attributes
305+
:param Dictionary methods:
306+
A dictionary with all methods
307+
:return:
308+
A FakeResource object with zoneName, zoneState, etc.
309+
"""
310+
# Set default attributes.
311+
host_name = uuid.uuid4().hex
312+
service_name = uuid.uuid4().hex
313+
service_updated_at = uuid.uuid4().hex
314+
availability_zone = {
315+
'zoneName': uuid.uuid4().hex,
316+
'zoneState': {'available': True},
317+
'hosts': {host_name: {service_name: {
318+
'available': True,
319+
'active': True,
320+
'updated_at': service_updated_at,
321+
}}},
322+
}
323+
324+
# Overwrite default attributes.
325+
availability_zone.update(attrs)
326+
327+
availability_zone = fakes.FakeResource(
328+
info=copy.deepcopy(availability_zone),
329+
methods=methods,
330+
loaded=True)
331+
return availability_zone
332+
333+
@staticmethod
334+
def create_availability_zones(attrs={}, methods={}, count=2):
335+
"""Create multiple fake AZs.
336+
337+
:param Dictionary attrs:
338+
A dictionary with all attributes
339+
:param Dictionary methods:
340+
A dictionary with all methods
341+
:param int count:
342+
The number of AZs to fake
343+
:return:
344+
A list of FakeResource objects faking the AZs
345+
"""
346+
availability_zones = []
347+
for i in range(0, count):
348+
availability_zone = \
349+
FakeAvailabilityZone.create_one_availability_zone(
350+
attrs, methods)
351+
availability_zones.append(availability_zone)
352+
353+
return availability_zones

setup.cfg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,14 @@ openstack.cli.base =
4343
volume = openstackclient.volume.client
4444

4545
openstack.common =
46+
availability_zone_list = openstackclient.common.availability_zone:ListAvailabilityZone
4647
configuration_show = openstackclient.common.configuration:ShowConfiguration
4748
extension_list = openstackclient.common.extension:ListExtension
4849
limits_show = openstackclient.common.limits:ShowLimits
4950
quota_set = openstackclient.common.quota:SetQuota
5051
quota_show = openstackclient.common.quota:ShowQuota
5152

5253
openstack.compute.v2 =
53-
availability_zone_list = openstackclient.compute.v2.availability_zone:ListAvailabilityZone
54-
5554
compute_agent_create = openstackclient.compute.v2.agent:CreateAgent
5655
compute_agent_delete = openstackclient.compute.v2.agent:DeleteAgent
5756
compute_agent_list = openstackclient.compute.v2.agent:ListAgent

0 commit comments

Comments
 (0)