blob: a2302b6f4172d7cd8d34593f511ea508a71626f8 [file] [log] [blame]
Matthew Treinishc791ac42014-07-16 09:15:23 -04001# Copyright 2014 Hewlett-Packard Development Company, L.P.
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
15import hashlib
16import os
17import tempfile
18
19import mock
20from oslo.config import cfg
21from oslotest import mockpatch
22
23from tempest import auth
24from tempest.common import accounts
Matthew Treinishc791ac42014-07-16 09:15:23 -040025from tempest import config
26from tempest import exceptions
ghanshyamc0edda02015-02-06 15:51:40 +090027from tempest.services.identity.json import token_client
Matthew Treinishc791ac42014-07-16 09:15:23 -040028from tempest.tests import base
29from tempest.tests import fake_config
30from tempest.tests import fake_identity
31
32
33class TestAccount(base.TestCase):
34
35 def setUp(self):
36 super(TestAccount, self).setUp()
37 self.useFixture(fake_config.ConfigFixture())
38 self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
39 self.temp_dir = tempfile.mkdtemp()
40 cfg.CONF.set_default('lock_path', self.temp_dir)
41 self.addCleanup(os.rmdir, self.temp_dir)
42 self.test_accounts = [
43 {'username': 'test_user1', 'tenant_name': 'test_tenant1',
44 'password': 'p'},
45 {'username': 'test_user2', 'tenant_name': 'test_tenant2',
46 'password': 'p'},
47 {'username': 'test_user3', 'tenant_name': 'test_tenant3',
48 'password': 'p'},
49 {'username': 'test_user4', 'tenant_name': 'test_tenant4',
50 'password': 'p'},
51 {'username': 'test_user5', 'tenant_name': 'test_tenant5',
52 'password': 'p'},
53 {'username': 'test_user6', 'tenant_name': 'test_tenant6',
Matthew Treinish976e8df2014-12-19 14:21:54 -050054 'password': 'p', 'roles': ['role1', 'role2']},
55 {'username': 'test_user7', 'tenant_name': 'test_tenant7',
56 'password': 'p', 'roles': ['role2', 'role3']},
57 {'username': 'test_user8', 'tenant_name': 'test_tenant8',
58 'password': 'p', 'roles': ['role4', 'role1']},
59 {'username': 'test_user9', 'tenant_name': 'test_tenant9',
60 'password': 'p', 'roles': ['role1', 'role2', 'role3', 'role4']},
61 {'username': 'test_user10', 'tenant_name': 'test_tenant10',
62 'password': 'p', 'roles': ['role1', 'role2', 'role3', 'role4']},
63 {'username': 'test_user11', 'tenant_name': 'test_tenant11',
64 'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
65 {'username': 'test_user12', 'tenant_name': 'test_tenant12',
66 'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
Matthew Treinishc791ac42014-07-16 09:15:23 -040067 ]
68 self.useFixture(mockpatch.Patch(
69 'tempest.common.accounts.read_accounts_yaml',
70 return_value=self.test_accounts))
71 cfg.CONF.set_default('test_accounts_file', '', group='auth')
Matthew Treinishb19eeb82014-09-04 09:57:46 -040072 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
Matthew Treinishc791ac42014-07-16 09:15:23 -040073
74 def _get_hash_list(self, accounts_list):
75 hash_list = []
76 for account in accounts_list:
77 hash = hashlib.md5()
78 hash.update(str(account))
Matthew Treinish976e8df2014-12-19 14:21:54 -050079 temp_hash = hash.hexdigest()
80 hash_list.append(temp_hash)
Matthew Treinishc791ac42014-07-16 09:15:23 -040081 return hash_list
82
83 def test_get_hash(self):
ghanshyamc0edda02015-02-06 15:51:40 +090084 self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
Matthew Treinishc791ac42014-07-16 09:15:23 -040085 fake_identity._fake_v2_response)
86 test_account_class = accounts.Accounts('test_name')
87 hash_list = self._get_hash_list(self.test_accounts)
88 test_cred_dict = self.test_accounts[3]
ghanshyam5ff763f2015-02-18 16:15:58 +090089 test_creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
90 **test_cred_dict)
Matthew Treinishc791ac42014-07-16 09:15:23 -040091 results = test_account_class.get_hash(test_creds)
92 self.assertEqual(hash_list[3], results)
93
94 def test_get_hash_dict(self):
95 test_account_class = accounts.Accounts('test_name')
96 hash_dict = test_account_class.get_hash_dict(self.test_accounts)
97 hash_list = self._get_hash_list(self.test_accounts)
98 for hash in hash_list:
Matthew Treinish976e8df2014-12-19 14:21:54 -050099 self.assertIn(hash, hash_dict['creds'].keys())
100 self.assertIn(hash_dict['creds'][hash], self.test_accounts)
Matthew Treinishc791ac42014-07-16 09:15:23 -0400101
102 def test_create_hash_file_previous_file(self):
103 # Emulate the lock existing on the filesystem
104 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
105 with mock.patch('__builtin__.open', mock.mock_open(), create=True):
106 test_account_class = accounts.Accounts('test_name')
107 res = test_account_class._create_hash_file('12345')
108 self.assertFalse(res, "_create_hash_file should return False if the "
109 "pseudo-lock file already exists")
110
111 def test_create_hash_file_no_previous_file(self):
112 # Emulate the lock not existing on the filesystem
113 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
114 with mock.patch('__builtin__.open', mock.mock_open(), create=True):
115 test_account_class = accounts.Accounts('test_name')
116 res = test_account_class._create_hash_file('12345')
117 self.assertTrue(res, "_create_hash_file should return True if the "
118 "pseudo-lock doesn't already exist")
119
120 @mock.patch('tempest.openstack.common.lockutils.lock')
121 def test_get_free_hash_no_previous_accounts(self, lock_mock):
122 # Emulate no pre-existing lock
123 self.useFixture(mockpatch.Patch('os.path.isdir', return_value=False))
124 hash_list = self._get_hash_list(self.test_accounts)
125 mkdir_mock = self.useFixture(mockpatch.Patch('os.mkdir'))
126 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
127 test_account_class = accounts.Accounts('test_name')
128 with mock.patch('__builtin__.open', mock.mock_open(),
129 create=True) as open_mock:
130 test_account_class._get_free_hash(hash_list)
131 lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
132 hash_list[0])
133 open_mock.assert_called_once_with(lock_path, 'w')
134 mkdir_path = os.path.join(accounts.CONF.lock_path, 'test_accounts')
135 mkdir_mock.mock.assert_called_once_with(mkdir_path)
136
137 @mock.patch('tempest.openstack.common.lockutils.lock')
138 def test_get_free_hash_no_free_accounts(self, lock_mock):
139 hash_list = self._get_hash_list(self.test_accounts)
140 # Emulate pre-existing lock dir
141 self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
142 # Emulate all lcoks in list are in use
143 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
144 test_account_class = accounts.Accounts('test_name')
Matthew Treinish4041b262015-02-27 11:18:54 -0500145 with mock.patch('__builtin__.open', mock.mock_open(), create=True):
146 self.assertRaises(exceptions.InvalidConfiguration,
147 test_account_class._get_free_hash, hash_list)
Matthew Treinishc791ac42014-07-16 09:15:23 -0400148
149 @mock.patch('tempest.openstack.common.lockutils.lock')
150 def test_get_free_hash_some_in_use_accounts(self, lock_mock):
151 # Emulate no pre-existing lock
152 self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
153 hash_list = self._get_hash_list(self.test_accounts)
154 test_account_class = accounts.Accounts('test_name')
155
156 def _fake_is_file(path):
157 # Fake isfile() to return that the path exists unless a specific
158 # hash is in the path
159 if hash_list[3] in path:
160 return False
161 return True
162
163 self.stubs.Set(os.path, 'isfile', _fake_is_file)
164 with mock.patch('__builtin__.open', mock.mock_open(),
165 create=True) as open_mock:
166 test_account_class._get_free_hash(hash_list)
167 lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
168 hash_list[3])
Matthew Treinish4041b262015-02-27 11:18:54 -0500169 open_mock.assert_has_calls([mock.call(lock_path, 'w')])
Matthew Treinishc791ac42014-07-16 09:15:23 -0400170
171 @mock.patch('tempest.openstack.common.lockutils.lock')
172 def test_remove_hash_last_account(self, lock_mock):
173 hash_list = self._get_hash_list(self.test_accounts)
174 # Pretend the pseudo-lock is there
175 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
176 # Pretend the lock dir is empty
177 self.useFixture(mockpatch.Patch('os.listdir', return_value=[]))
178 test_account_class = accounts.Accounts('test_name')
179 remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
180 rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
181 test_account_class.remove_hash(hash_list[2])
182 hash_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
183 hash_list[2])
184 lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts')
185 remove_mock.mock.assert_called_once_with(hash_path)
186 rmdir_mock.mock.assert_called_once_with(lock_path)
187
188 @mock.patch('tempest.openstack.common.lockutils.lock')
189 def test_remove_hash_not_last_account(self, lock_mock):
190 hash_list = self._get_hash_list(self.test_accounts)
191 # Pretend the pseudo-lock is there
192 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
193 # Pretend the lock dir is empty
194 self.useFixture(mockpatch.Patch('os.listdir', return_value=[
195 hash_list[1], hash_list[4]]))
196 test_account_class = accounts.Accounts('test_name')
197 remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
198 rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
199 test_account_class.remove_hash(hash_list[2])
200 hash_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
201 hash_list[2])
202 remove_mock.mock.assert_called_once_with(hash_path)
203 rmdir_mock.mock.assert_not_called()
Matthew Treinish09f17832014-08-15 15:22:50 -0400204
205 def test_is_multi_user(self):
206 test_accounts_class = accounts.Accounts('test_name')
207 self.assertTrue(test_accounts_class.is_multi_user())
208
209 def test_is_not_multi_user(self):
210 self.test_accounts = [self.test_accounts[0]]
211 self.useFixture(mockpatch.Patch(
212 'tempest.common.accounts.read_accounts_yaml',
213 return_value=self.test_accounts))
214 test_accounts_class = accounts.Accounts('test_name')
215 self.assertFalse(test_accounts_class.is_multi_user())
Andrea Frittolib1c23fc2014-09-03 13:40:08 +0100216
Matthew Treinish976e8df2014-12-19 14:21:54 -0500217 def test__get_creds_by_roles_one_role(self):
218 self.useFixture(mockpatch.Patch(
219 'tempest.common.accounts.read_accounts_yaml',
220 return_value=self.test_accounts))
221 test_accounts_class = accounts.Accounts('test_name')
222 hashes = test_accounts_class.hash_dict['roles']['role4']
223 temp_hash = hashes[0]
224 get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
225 test_accounts_class, '_get_free_hash', return_value=temp_hash))
226 # Test a single role returns all matching roles
227 test_accounts_class._get_creds(roles=['role4'])
228 calls = get_free_hash_mock.mock.mock_calls
229 self.assertEqual(len(calls), 1)
230 args = calls[0][1][0]
231 for i in hashes:
232 self.assertIn(i, args)
233
234 def test__get_creds_by_roles_list_role(self):
235 self.useFixture(mockpatch.Patch(
236 'tempest.common.accounts.read_accounts_yaml',
237 return_value=self.test_accounts))
238 test_accounts_class = accounts.Accounts('test_name')
239 hashes = test_accounts_class.hash_dict['roles']['role4']
240 hashes2 = test_accounts_class.hash_dict['roles']['role2']
241 hashes = list(set(hashes) & set(hashes2))
242 temp_hash = hashes[0]
243 get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
244 test_accounts_class, '_get_free_hash', return_value=temp_hash))
245 # Test an intersection of multiple roles
246 test_accounts_class._get_creds(roles=['role2', 'role4'])
247 calls = get_free_hash_mock.mock.mock_calls
248 self.assertEqual(len(calls), 1)
249 args = calls[0][1][0]
250 for i in hashes:
251 self.assertIn(i, args)
252
253 def test__get_creds_by_roles_no_admin(self):
254 self.useFixture(mockpatch.Patch(
255 'tempest.common.accounts.read_accounts_yaml',
256 return_value=self.test_accounts))
257 test_accounts_class = accounts.Accounts('test_name')
258 hashes = test_accounts_class.hash_dict['creds'].keys()
259 admin_hashes = test_accounts_class.hash_dict['roles'][
260 cfg.CONF.identity.admin_role]
261 temp_hash = hashes[0]
262 get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
263 test_accounts_class, '_get_free_hash', return_value=temp_hash))
264 # Test an intersection of multiple roles
265 test_accounts_class._get_creds()
266 calls = get_free_hash_mock.mock.mock_calls
267 self.assertEqual(len(calls), 1)
268 args = calls[0][1][0]
269 self.assertEqual(len(args), 10)
270 for i in admin_hashes:
271 self.assertNotIn(i, args)
272
Andrea Frittolib1c23fc2014-09-03 13:40:08 +0100273
274class TestNotLockingAccount(base.TestCase):
275
276 def setUp(self):
277 super(TestNotLockingAccount, self).setUp()
278 self.useFixture(fake_config.ConfigFixture())
279 self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
280 self.temp_dir = tempfile.mkdtemp()
281 cfg.CONF.set_default('lock_path', self.temp_dir)
282 self.addCleanup(os.rmdir, self.temp_dir)
283 self.test_accounts = [
284 {'username': 'test_user1', 'tenant_name': 'test_tenant1',
285 'password': 'p'},
286 {'username': 'test_user2', 'tenant_name': 'test_tenant2',
287 'password': 'p'},
288 {'username': 'test_user3', 'tenant_name': 'test_tenant3',
289 'password': 'p'},
290 ]
291 self.useFixture(mockpatch.Patch(
292 'tempest.common.accounts.read_accounts_yaml',
293 return_value=self.test_accounts))
294 cfg.CONF.set_default('test_accounts_file', '', group='auth')
Matthew Treinishb19eeb82014-09-04 09:57:46 -0400295 self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
Andrea Frittolib1c23fc2014-09-03 13:40:08 +0100296
297 def test_get_creds(self):
298 test_accounts_class = accounts.NotLockingAccounts('test_name')
299 for i in xrange(len(self.test_accounts)):
300 creds = test_accounts_class.get_creds(i)
301 msg = "Empty credentials returned for ID %s" % str(i)
302 self.assertIsNotNone(creds, msg)
303 self.assertRaises(exceptions.InvalidConfiguration,
304 test_accounts_class.get_creds,
Matthew Treinishb19eeb82014-09-04 09:57:46 -0400305 id=len(self.test_accounts))