Skip to content

Commit 941217a

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Support for volume service list"
2 parents 74162fa + 4072554 commit 941217a

10 files changed

Lines changed: 649 additions & 0 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
==============
2+
volume service
3+
==============
4+
5+
Volume v1, v2
6+
7+
volume service list
8+
-------------------
9+
10+
List volume service
11+
12+
.. program:: volume service list
13+
.. code:: bash
14+
15+
os volume service list
16+
[--host <host>]
17+
[--service <service>]
18+
[--long]
19+
20+
.. _volume-service-list:
21+
.. option:: --host <host>
22+
23+
List services on specified host (name only)
24+
25+
.. option:: --service <service>
26+
27+
List only specified service (name only)
28+
29+
.. option:: --long
30+
31+
List additional fields in output

doc/source/commands.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ referring to both Compute and Volume quotas.
133133
* ``volume``: (**Volume**) block volumes
134134
* ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes
135135
* ``volume type``: (**Volume**) deployment-specific types of volumes available
136+
* ``volume service``: (**Volume**) services to manage block storage operations
136137

137138

138139
Plugin Objects

openstackclient/tests/volume/v1/fakes.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,97 @@
129129
}
130130

131131

132+
class FakeServiceClient(object):
133+
134+
def __init__(self, **kwargs):
135+
self.services = mock.Mock()
136+
self.services.resource_class = fakes.FakeResource(None, {})
137+
138+
139+
class TestService(utils.TestCommand):
140+
141+
def setUp(self):
142+
super(TestService, self).setUp()
143+
144+
self.app.client_manager.volume = FakeServiceClient(
145+
endpoint=fakes.AUTH_URL,
146+
token=fakes.AUTH_TOKEN
147+
)
148+
149+
150+
class FakeService(object):
151+
"""Fake one or more Services."""
152+
153+
@staticmethod
154+
def create_one_service(attrs=None):
155+
"""Create a fake service.
156+
157+
:param Dictionary attrs:
158+
A dictionary with all attributes of service
159+
:retrun:
160+
A FakeResource object with host, status, etc.
161+
"""
162+
# Set default attribute
163+
service_info = {
164+
'host': 'host_test',
165+
'binary': 'cinder_test',
166+
'status': 'enabled',
167+
'disabled_reason': 'LongHoliday-GoldenWeek',
168+
'zone': 'fake_zone',
169+
'updated_at': 'fake_date',
170+
'state': 'fake_state',
171+
}
172+
173+
# Overwrite default attributes if there are some attributes set
174+
if attrs is None:
175+
attrs = {}
176+
service_info.update(attrs)
177+
178+
service = fakes.FakeResource(
179+
None,
180+
service_info,
181+
loaded=True)
182+
183+
return service
184+
185+
@staticmethod
186+
def create_services(attrs=None, count=2):
187+
"""Create multiple fake services.
188+
189+
:param Dictionary attrs:
190+
A dictionary with all attributes of service
191+
:param Integer count:
192+
The number of services to be faked
193+
:return:
194+
A list of FakeResource objects
195+
"""
196+
services = []
197+
for n in range(0, count):
198+
services.append(FakeService.create_one_service(attrs))
199+
200+
return services
201+
202+
@staticmethod
203+
def get_services(services=None, count=2):
204+
"""Get an iterable MagicMock object with a list of faked services.
205+
206+
If services list is provided, then initialize the Mock object with the
207+
list. Otherwise create one.
208+
209+
:param List services:
210+
A list of FakeResource objects faking services
211+
:param Integer count:
212+
The number of services to be faked
213+
:return
214+
An iterable Mock object with side_effect set to a list of faked
215+
services
216+
"""
217+
if services is None:
218+
services = FakeService.create_services(count)
219+
220+
return mock.MagicMock(side_effect=services)
221+
222+
132223
class FakeImagev1Client(object):
133224

134225
def __init__(self, **kwargs):
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
#
14+
15+
16+
from openstackclient.tests.volume.v1 import fakes as service_fakes
17+
from openstackclient.volume.v1 import service
18+
19+
20+
class TestService(service_fakes.TestService):
21+
22+
def setUp(self):
23+
super(TestService, self).setUp()
24+
25+
# Get a shortcut to the ServiceManager Mock
26+
self.service_mock = self.app.client_manager.volume.services
27+
self.service_mock.reset_mock()
28+
29+
30+
class TestServiceList(TestService):
31+
32+
# The service to be listed
33+
services = service_fakes.FakeService.create_one_service()
34+
35+
def setUp(self):
36+
super(TestServiceList, self).setUp()
37+
38+
self.service_mock.list.return_value = [self.services]
39+
40+
# Get the command object to test
41+
self.cmd = service.ListService(self.app, None)
42+
43+
def test_service_list(self):
44+
arglist = [
45+
'--host', self.services.host,
46+
'--service', self.services.binary,
47+
]
48+
verifylist = [
49+
('host', self.services.host),
50+
('service', self.services.binary),
51+
]
52+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
53+
54+
# In base command class Lister in cliff, abstract method take_action()
55+
# returns a tuple containing the column names and an iterable
56+
# containing the data to be listed.
57+
columns, data = self.cmd.take_action(parsed_args)
58+
59+
expected_columns = [
60+
'Binary',
61+
'Host',
62+
'Zone',
63+
'Status',
64+
'State',
65+
'Updated At',
66+
]
67+
68+
# confirming if all expected columns are present in the result.
69+
self.assertEqual(expected_columns, columns)
70+
71+
datalist = ((
72+
self.services.binary,
73+
self.services.host,
74+
self.services.zone,
75+
self.services.status,
76+
self.services.state,
77+
self.services.updated_at,
78+
), )
79+
80+
# confirming if all expected values are present in the result.
81+
self.assertEqual(datalist, tuple(data))
82+
83+
# checking if proper call was made to list services
84+
self.service_mock.list.assert_called_with(
85+
self.services.host,
86+
self.services.binary,
87+
)
88+
89+
# checking if prohibited columns are present in output
90+
self.assertNotIn("Disabled Reason", columns)
91+
self.assertNotIn(self.services.disabled_reason,
92+
tuple(data))
93+
94+
def test_service_list_with_long_option(self):
95+
arglist = [
96+
'--host', self.services.host,
97+
'--service', self.services.binary,
98+
'--long'
99+
]
100+
verifylist = [
101+
('host', self.services.host),
102+
('service', self.services.binary),
103+
('long', True)
104+
]
105+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
106+
107+
# In base command class Lister in cliff, abstract method take_action()
108+
# returns a tuple containing the column names and an iterable
109+
# containing the data to be listed.
110+
columns, data = self.cmd.take_action(parsed_args)
111+
112+
expected_columns = [
113+
'Binary',
114+
'Host',
115+
'Zone',
116+
'Status',
117+
'State',
118+
'Updated At',
119+
'Disabled Reason'
120+
]
121+
122+
# confirming if all expected columns are present in the result.
123+
self.assertEqual(expected_columns, columns)
124+
125+
datalist = ((
126+
self.services.binary,
127+
self.services.host,
128+
self.services.zone,
129+
self.services.status,
130+
self.services.state,
131+
self.services.updated_at,
132+
self.services.disabled_reason,
133+
), )
134+
135+
# confirming if all expected values are present in the result.
136+
self.assertEqual(datalist, tuple(data))
137+
138+
self.service_mock.list.assert_called_with(
139+
self.services.host,
140+
self.services.binary,
141+
)

openstackclient/tests/volume/v2/fakes.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,97 @@
232232
}
233233

234234

235+
class FakeServiceClient(object):
236+
237+
def __init__(self, **kwargs):
238+
self.services = mock.Mock()
239+
self.services.resource_class = fakes.FakeResource(None, {})
240+
241+
242+
class TestService(utils.TestCommand):
243+
244+
def setUp(self):
245+
super(TestService, self).setUp()
246+
247+
self.app.client_manager.volume = FakeServiceClient(
248+
endpoint=fakes.AUTH_URL,
249+
token=fakes.AUTH_TOKEN
250+
)
251+
252+
253+
class FakeService(object):
254+
"""Fake one or more Services."""
255+
256+
@staticmethod
257+
def create_one_service(attrs=None):
258+
"""Create a fake service.
259+
260+
:param Dictionary attrs:
261+
A dictionary with all attributes of service
262+
:retrun:
263+
A FakeResource object with host, status, etc.
264+
"""
265+
# Set default attribute
266+
service_info = {
267+
'host': 'host_test',
268+
'binary': 'cinder_test',
269+
'status': 'enabled',
270+
'disabled_reason': 'LongHoliday-GoldenWeek',
271+
'zone': 'fake_zone',
272+
'updated_at': 'fake_date',
273+
'state': 'fake_state',
274+
}
275+
276+
# Overwrite default attributes if there are some attributes set
277+
if attrs is None:
278+
attrs = {}
279+
service_info.update(attrs)
280+
281+
service = fakes.FakeResource(
282+
None,
283+
service_info,
284+
loaded=True)
285+
286+
return service
287+
288+
@staticmethod
289+
def create_services(attrs=None, count=2):
290+
"""Create multiple fake services.
291+
292+
:param Dictionary attrs:
293+
A dictionary with all attributes of service
294+
:param Integer count:
295+
The number of services to be faked
296+
:return:
297+
A list of FakeResource objects
298+
"""
299+
services = []
300+
for n in range(0, count):
301+
services.append(FakeService.create_one_service(attrs))
302+
303+
return services
304+
305+
@staticmethod
306+
def get_services(services=None, count=2):
307+
"""Get an iterable MagicMock object with a list of faked services.
308+
309+
If services list is provided, then initialize the Mock object with the
310+
list. Otherwise create one.
311+
312+
:param List services:
313+
A list of FakeResource objects faking services
314+
:param Integer count:
315+
The number of services to be faked
316+
:return
317+
An iterable Mock object with side_effect set to a list of faked
318+
services
319+
"""
320+
if services is None:
321+
services = FakeService.create_services(count)
322+
323+
return mock.MagicMock(side_effect=services)
324+
325+
235326
class FakeVolumeClient(object):
236327

237328
def __init__(self, **kwargs):

0 commit comments

Comments
 (0)