Skip to content

Commit 493339d

Browse files
author
Dean Troyer
committed
Add Identity v2 project tests
* establish the the form of cliff command classes * implement some common fake objects * implement Identity command tests for v2 project * fix stdout/stderr capture Also re-work the project create and set commands for exclusive options (--enable|--disable) to actually behave properly. Yay tests! Change-Id: Icbb313db544c1f8dd3c9af7709971838b5a4d115
1 parent 93612bb commit 493339d

8 files changed

Lines changed: 533 additions & 24 deletions

File tree

‎.testr.conf‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
[DEFAULT]
2-
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
2+
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
3+
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
4+
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
5+
${PYTHON:-python} -m subunit.run discover -t ./ ./openstackclient/tests $LISTOPT $IDOPTION
6+
37
test_id_option=--load-list $IDFILE
48
test_list_option=--list

‎openstackclient/identity/v2_0/project.py‎

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,28 @@ def get_parser(self, prog_name):
4545
enable_group = parser.add_mutually_exclusive_group()
4646
enable_group.add_argument(
4747
'--enable',
48-
dest='enabled',
4948
action='store_true',
50-
default=True,
51-
help='Enable project',
49+
help='Enable project (default)',
5250
)
5351
enable_group.add_argument(
5452
'--disable',
55-
dest='enabled',
56-
action='store_false',
53+
action='store_true',
5754
help='Disable project',
5855
)
5956
return parser
6057

6158
def take_action(self, parsed_args):
6259
self.log.debug('take_action(%s)' % parsed_args)
60+
6361
identity_client = self.app.client_manager.identity
62+
enabled = True
63+
if parsed_args.disable:
64+
enabled = False
6465
project = identity_client.tenants.create(
6566
parsed_args.project_name,
6667
description=parsed_args.description,
67-
enabled=parsed_args.enabled)
68+
enabled=enabled,
69+
)
6870

6971
info = {}
7072
info.update(project._info)
@@ -150,36 +152,44 @@ def get_parser(self, prog_name):
150152
enable_group = parser.add_mutually_exclusive_group()
151153
enable_group.add_argument(
152154
'--enable',
153-
dest='enabled',
154155
action='store_true',
155-
default=True,
156-
help='Enable project (default)',
156+
help='Enable project',
157157
)
158158
enable_group.add_argument(
159159
'--disable',
160-
dest='enabled',
161-
action='store_false',
160+
action='store_true',
162161
help='Disable project',
163162
)
164163
return parser
165164

166165
def take_action(self, parsed_args):
167166
self.log.debug('take_action(%s)' % parsed_args)
167+
168168
identity_client = self.app.client_manager.identity
169169
project = utils.find_resource(
170170
identity_client.tenants,
171171
parsed_args.project,
172172
)
173-
kwargs = {}
173+
174+
kwargs = project._info
174175
if parsed_args.name:
175176
kwargs['name'] = parsed_args.name
176177
if parsed_args.description:
177178
kwargs['description'] = parsed_args.description
178-
if 'enabled' in parsed_args:
179-
kwargs['enabled'] = parsed_args.enabled
180-
181-
project.update(**kwargs)
182-
return
179+
if parsed_args.enable:
180+
kwargs['enabled'] = True
181+
if parsed_args.disable:
182+
kwargs['enabled'] = False
183+
184+
if 'id' in kwargs:
185+
del kwargs['id']
186+
if 'name' in kwargs:
187+
# Hack around borken Identity API arg names
188+
kwargs['tenant_name'] = kwargs['name']
189+
del kwargs['name']
190+
191+
if len(kwargs):
192+
identity_client.tenants.update(project.id, **kwargs)
183193

184194

185195
class ShowProject(show.ShowOne):

‎openstackclient/tests/fakes.py‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright 2013 Nebula Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
import sys
17+
18+
19+
class FakeStdout:
20+
def __init__(self):
21+
self.content = []
22+
23+
def write(self, text):
24+
self.content.append(text)
25+
26+
def make_string(self):
27+
result = ''
28+
for line in self.content:
29+
result = result + line
30+
return result
31+
32+
33+
class FakeApp(object):
34+
def __init__(self, _stdout):
35+
self.stdout = _stdout
36+
self.client_manager = None
37+
self.stdin = sys.stdin
38+
self.stdout = _stdout or sys.stdout
39+
self.stderr = sys.stderr
40+
41+
42+
class FakeClientManager(object):
43+
def __init__(self):
44+
pass
45+
46+
47+
class FakeResource(object):
48+
def __init__(self, manager, info, loaded=False):
49+
self.manager = manager
50+
self._info = info
51+
self._add_details(info)
52+
self._loaded = loaded
53+
54+
def _add_details(self, info):
55+
for (k, v) in info.iteritems():
56+
setattr(self, k, v)
57+
58+
def __repr__(self):
59+
reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and
60+
k != 'manager')
61+
info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
62+
return "<%s %s>" % (self.__class__.__name__, info)

‎openstackclient/tests/identity/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2013 OpenStack, LLC.
1+
# Copyright 2013 OpenStack Foundation
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License"); you may
44
# not use this file except in compliance with the License. You may obtain
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2013 Nebula Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
import mock
17+
18+
from openstackclient.tests import fakes
19+
20+
21+
class FakeIdentityv2Client(object):
22+
def __init__(self, **kwargs):
23+
self.tenants = mock.Mock()
24+
self.tenants.resource_class = fakes.FakeResource(None, {})
25+
self.users = mock.Mock()
26+
self.users.resource_class = fakes.FakeResource(None, {})
27+
self.ec2 = mock.Mock()
28+
self.ec2.resource_class = fakes.FakeResource(None, {})
29+
self.auth_tenant_id = 'fake-tenant'
30+
self.auth_user_id = 'fake-user'
31+
32+
33+
class FakeIdentityv3Client(object):
34+
def __init__(self, **kwargs):
35+
self.domains = mock.Mock()
36+
self.domains.resource_class = fakes.FakeResource(None, {})
37+
self.projects = mock.Mock()
38+
self.projects.resource_class = fakes.FakeResource(None, {})
39+
self.users = mock.Mock()
40+
self.users.resource_class = fakes.FakeResource(None, {})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright 2013 OpenStack Foundation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#

0 commit comments

Comments
 (0)