Skip to content

Commit aa3b3c1

Browse files
author
Guojian Shao
committed
add functional tests for identity v3
To make test cases more clearly, split test_identity.py into test_user.py, test_role, etc. Add more test cases for user, role, etc. Furthermore, to make functional tests run repeatedly without raising duplicated error, clean up resources before exiting each test case. Change-Id: I1541943ad0b8d4d8d1e72822c159fda243b3d1d7 Implements: blueprint identity-functional-tests
1 parent 60d1417 commit aa3b3c1

10 files changed

Lines changed: 785 additions & 60 deletions

File tree

‎functional/common/test.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ def assert_show_fields(self, items, field_names):
8989
for key in six.iterkeys(item):
9090
self.assertIn(key, field_names)
9191

92+
def assert_show_structure(self, items, field_names):
93+
"""Verify that all field_names listed in keys of all items."""
94+
if isinstance(items, list):
95+
o = {}
96+
for d in items:
97+
o.update(d)
98+
else:
99+
o = items
100+
item_keys = o.keys()
101+
for field in field_names:
102+
self.assertIn(field, item_keys)
103+
104+
def parse_show_as_object(self, raw_output):
105+
"""Return a dict with values parsed from cli output."""
106+
items = self.parse_show(raw_output)
107+
o = {}
108+
for item in items:
109+
o.update(item)
110+
return o
111+
92112
def parse_show(self, raw_output):
93113
"""Return list of dicts with item values parsed from cli output."""
94114

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.tests.identity.v3 import test_identity
14+
15+
16+
class CatalogTests(test_identity.IdentityTests):
17+
18+
def test_catalog_list(self):
19+
raw_output = self.openstack('catalog list')
20+
items = self.parse_listing(raw_output)
21+
self.assert_table_structure(items, ['Name', 'Type', 'Endpoints'])
22+
23+
def test_catalog_show(self):
24+
"""test catalog show command
25+
26+
The output example:
27+
+-----------+-------------------------------------------+
28+
| Field | Value |
29+
+-----------+-------------------------------------------+
30+
| endpoints | test1 |
31+
| | publicURL: http://localhost:5000/v2.0 |
32+
| | internalURL: http://localhost:5000/v2.0 |
33+
| | adminURL: http://localhost:5000/v2.0 |
34+
| | |
35+
| name | keystone |
36+
| type | identity |
37+
+-----------+-------------------------------------------+
38+
"""
39+
raw_output = self.openstack('catalog show %s' % 'identity')
40+
items = self.parse_show(raw_output)
41+
# items may have multiple endpoint urls with empty key
42+
self.assert_show_fields(items, ['endpoints', 'name', 'type', '', 'id'])
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 tempest_lib.common.utils import data_utils
14+
15+
from functional.common import exceptions
16+
from functional.tests.identity.v3 import test_identity
17+
18+
19+
class DomainTests(test_identity.IdentityTests):
20+
21+
def test_domain_create(self):
22+
domain_name = data_utils.rand_name('TestDomain')
23+
raw_output = self.openstack('domain create %s' % domain_name)
24+
items = self.parse_show(raw_output)
25+
self.assert_show_fields(items, self.DOMAIN_FIELDS)
26+
# disable domain first before deleting it
27+
self.addCleanup(self.openstack,
28+
'domain delete %s' % domain_name)
29+
self.addCleanup(self.openstack,
30+
'domain set --disable %s' % domain_name)
31+
32+
def test_domain_list(self):
33+
self._create_dummy_domain()
34+
raw_output = self.openstack('domain list')
35+
items = self.parse_listing(raw_output)
36+
self.assert_table_structure(items, test_identity.BASIC_LIST_HEADERS)
37+
38+
def test_domain_delete(self):
39+
domain_name = self._create_dummy_domain(add_clean_up=False)
40+
# cannot delete enabled domain, disable it first
41+
raw_output = self.openstack('domain set --disable %s' % domain_name)
42+
self.assertEqual(0, len(raw_output))
43+
raw_output = self.openstack('domain delete %s' % domain_name)
44+
self.assertEqual(0, len(raw_output))
45+
46+
def test_domain_delete_failure(self):
47+
domain_name = self._create_dummy_domain()
48+
# cannot delete enabled domain
49+
self.assertRaises(exceptions.CommandFailed,
50+
self.openstack,
51+
'domain delete %s' % domain_name)
52+
53+
def test_domain_show(self):
54+
domain_name = self._create_dummy_domain()
55+
raw_output = self.openstack('domain show %s' % domain_name)
56+
items = self.parse_show(raw_output)
57+
self.assert_show_fields(items, self.DOMAIN_FIELDS)
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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 tempest_lib.common.utils import data_utils
14+
15+
from functional.tests.identity.v3 import test_identity
16+
17+
18+
class GroupTests(test_identity.IdentityTests):
19+
20+
def test_group_create(self):
21+
self._create_dummy_group()
22+
23+
def test_group_list(self):
24+
group_name = self._create_dummy_group()
25+
raw_output = self.openstack('group list')
26+
items = self.parse_listing(raw_output)
27+
self.assert_table_structure(items, test_identity.BASIC_LIST_HEADERS)
28+
self.assertInOutput(group_name, raw_output)
29+
30+
def test_group_list_with_domain(self):
31+
group_name = self._create_dummy_group()
32+
raw_output = self.openstack(
33+
'group list --domain %s' % self.domain_name)
34+
items = self.parse_listing(raw_output)
35+
self.assert_table_structure(items, test_identity.BASIC_LIST_HEADERS)
36+
self.assertInOutput(group_name, raw_output)
37+
38+
def test_group_delete(self):
39+
group_name = self._create_dummy_group(add_clean_up=False)
40+
raw_output = self.openstack(
41+
'group delete '
42+
'--domain %(domain)s '
43+
'%(name)s' % {'domain': self.domain_name,
44+
'name': group_name})
45+
self.assertEqual(0, len(raw_output))
46+
47+
def test_group_show(self):
48+
group_name = self._create_dummy_group()
49+
raw_output = self.openstack(
50+
'group show '
51+
'--domain %(domain)s '
52+
'%(name)s' % {'domain': self.domain_name,
53+
'name': group_name})
54+
items = self.parse_show(raw_output)
55+
self.assert_show_fields(items, self.GROUP_FIELDS)
56+
57+
def test_group_set(self):
58+
group_name = self._create_dummy_group()
59+
new_group_name = data_utils.rand_name('NewTestGroup')
60+
raw_output = self.openstack(
61+
'group set '
62+
'--domain %(domain)s '
63+
'--name %(new_group)s '
64+
'%(group)s' % {'domain': self.domain_name,
65+
'new_group': new_group_name,
66+
'group': group_name})
67+
self.assertEqual(0, len(raw_output))
68+
raw_output = self.openstack(
69+
'group show '
70+
'--domain %(domain)s '
71+
'%(group)s' % {'domain': self.domain_name,
72+
'group': new_group_name})
73+
group = self.parse_show_as_object(raw_output)
74+
self.assertEqual(new_group_name, group['name'])
75+
# reset group name to make sure it will be cleaned up
76+
raw_output = self.openstack(
77+
'group set '
78+
'--domain %(domain)s '
79+
'--name %(new_group)s '
80+
'%(group)s' % {'domain': self.domain_name,
81+
'new_group': group_name,
82+
'group': new_group_name})
83+
self.assertEqual(0, len(raw_output))
84+
85+
def test_group_add_user(self):
86+
group_name = self._create_dummy_group()
87+
username = self._create_dummy_user()
88+
raw_output = self.openstack(
89+
'group add user '
90+
'--group-domain %(group_domain)s '
91+
'--user-domain %(user_domain)s '
92+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
93+
'user_domain': self.domain_name,
94+
'group': group_name,
95+
'user': username})
96+
self.assertOutput(
97+
'%(user)s added to group %(group)s\n' % {'user': username,
98+
'group': group_name},
99+
raw_output
100+
)
101+
self.addCleanup(
102+
self.openstack,
103+
'group remove user '
104+
'--group-domain %(group_domain)s '
105+
'--user-domain %(user_domain)s '
106+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
107+
'user_domain': self.domain_name,
108+
'group': group_name,
109+
'user': username})
110+
111+
def test_group_contains_user(self):
112+
group_name = self._create_dummy_group()
113+
username = self._create_dummy_user()
114+
raw_output = self.openstack(
115+
'group add user '
116+
'--group-domain %(group_domain)s '
117+
'--user-domain %(user_domain)s '
118+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
119+
'user_domain': self.domain_name,
120+
'group': group_name,
121+
'user': username})
122+
self.assertOutput(
123+
'%(user)s added to group %(group)s\n' % {'user': username,
124+
'group': group_name},
125+
raw_output
126+
)
127+
raw_output = self.openstack(
128+
'group contains user '
129+
'--group-domain %(group_domain)s '
130+
'--user-domain %(user_domain)s '
131+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
132+
'user_domain': self.domain_name,
133+
'group': group_name,
134+
'user': username})
135+
self.assertOutput(
136+
'%(user)s in group %(group)s\n' % {'user': username,
137+
'group': group_name},
138+
raw_output)
139+
self.addCleanup(
140+
self.openstack,
141+
'group remove user '
142+
'--group-domain %(group_domain)s '
143+
'--user-domain %(user_domain)s '
144+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
145+
'user_domain': self.domain_name,
146+
'group': group_name,
147+
'user': username})
148+
149+
def test_group_remove_user(self):
150+
group_name = self._create_dummy_group()
151+
username = self._create_dummy_user()
152+
raw_output = self.openstack(
153+
'group add user '
154+
'--group-domain %(group_domain)s '
155+
'--user-domain %(user_domain)s '
156+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
157+
'user_domain': self.domain_name,
158+
'group': group_name,
159+
'user': username})
160+
self.assertOutput(
161+
'%(user)s added to group %(group)s\n' % {'user': username,
162+
'group': group_name},
163+
raw_output
164+
)
165+
raw_output = self.openstack(
166+
'group remove user '
167+
'--group-domain %(group_domain)s '
168+
'--user-domain %(user_domain)s '
169+
'%(group)s %(user)s' % {'group_domain': self.domain_name,
170+
'user_domain': self.domain_name,
171+
'group': group_name,
172+
'user': username})
173+
self.assertOutput(
174+
'%(user)s removed from '
175+
'group %(group)s\n' % {'user': username,
176+
'group': group_name},
177+
raw_output
178+
)

0 commit comments

Comments
 (0)