-
Notifications
You must be signed in to change notification settings - Fork 392
Expand file tree
/
Copy pathtest_scope.py
More file actions
286 lines (226 loc) · 12.8 KB
/
Copy pathtest_scope.py
File metadata and controls
286 lines (226 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# Copyright European Organization for Nuclear Research (CERN) since 2012
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from json import loads
import pytest
from rucio.common.exception import AccountNotFound, Duplicate, InvalidObject, ScopeNotFound
from rucio.common.types import InternalAccount, InternalScope
from rucio.common.utils import generate_uuid
from rucio.common.utils import generate_uuid as uuid
from rucio.core.scope import add_scope, get_scopes, is_scope_owner, list_scopes_with_account, update_scope
from rucio.db.sqla.constants import DatabaseOperationType
from rucio.db.sqla.session import db_session
from rucio.tests.common import account_name_generator, auth, hdrdict, headers, scope_name_generator
class TestScopeCoreApi:
def test_list_scopes(self, vo, jdoe_account):
scopes = [InternalScope(scope_name_generator(), vo=vo) for _ in range(5)]
""" SCOPE (CORE): List scopes """
with db_session(DatabaseOperationType.WRITE) as session:
for scope in scopes:
add_scope(scope=scope, account=jdoe_account, session=session)
scopes = get_scopes(account=jdoe_account, session=session)
for scope in scopes:
assert scope in scopes
def test_is_scope_owner(self, vo, jdoe_account):
""" SCOPE (CORE): Is scope owner """
scope = InternalScope(scope_name_generator(), vo=vo)
with db_session(DatabaseOperationType.WRITE) as session:
add_scope(scope=scope, account=jdoe_account, session=session)
answer = is_scope_owner(scope=scope, account=jdoe_account, session=session)
assert answer is True
def test_change_scope_owner(self, vo, jdoe_account, random_account):
""" SCOPE (CORE): Give the scope a different owner"""
scope = InternalScope(scope_name_generator(), vo=vo)
with db_session(DatabaseOperationType.WRITE) as session:
add_scope(scope=scope, account=jdoe_account, session=session)
anwser = is_scope_owner(scope, account=jdoe_account, session=session)
assert anwser
with db_session(DatabaseOperationType.WRITE) as session:
update_scope(scope=scope, account=random_account, session=session)
is_owner = is_scope_owner(scope, account=random_account, session=session)
is_not_owner = not is_scope_owner(scope, account=jdoe_account, session=session)
assert is_owner
assert is_not_owner
account = InternalAccount(account_name_generator())
with pytest.raises(AccountNotFound):
with db_session(DatabaseOperationType.WRITE) as session:
update_scope(scope=scope, account=account, session=session)
scope = InternalScope(scope_name_generator())
with pytest.raises(ScopeNotFound):
with db_session(DatabaseOperationType.WRITE) as session:
update_scope(scope=scope, account=random_account, session=session)
def test_list_scope_with_account(self, vo, jdoe_account):
scopes = [InternalScope(scope_name_generator(), vo=vo) for _ in range(5)]
""" SCOPE (CORE): List scopes """
with db_session(DatabaseOperationType.WRITE) as session:
for scope in scopes:
add_scope(scope=scope, account=jdoe_account, session=session)
with db_session(DatabaseOperationType.READ) as session:
listed_scopes = list_scopes_with_account(session=session)
for scope in listed_scopes:
assert set(scope.keys()) == set(["scope", "account"])
for scope in scopes:
assert scope in [s['scope'] for s in listed_scopes]
assert jdoe_account == [s['account'] for s in listed_scopes if s['scope'] == scope][0]
def test_scope_success(rest_client, auth_token):
""" SCOPE (REST): send a POST to create a new account and scope """
acntusr = account_name_generator()
data = {'type': 'USER', 'email': 'rucio.email.com'}
response = rest_client.post('/accounts/' + acntusr, headers=headers(auth(auth_token)), json=data)
assert response.status_code == 201
scopeusr = scope_name_generator()
response = rest_client.post('/accounts/%s/scopes/%s' % (acntusr, scopeusr), headers=headers(auth(auth_token)))
assert response.status_code == 201
def test_scope_failure(rest_client, auth_token):
""" SCOPE (REST): send a POST to create a new scope for a not existing account to test the error"""
scopeusr = scope_name_generator()
account_name_generator()
response = rest_client.post('/accounts/%s/scopes/%s' % (scopeusr, scopeusr), headers=headers(auth(auth_token)))
assert response.status_code == 404
def test_scope_duplicate(rest_client, auth_token):
""" SCOPE (REST): send a POST to create a already existing scope to test the error"""
acntusr = account_name_generator()
data = {'type': 'USER', 'email': '[email protected]'}
response = rest_client.post('/accounts/' + acntusr, headers=headers(auth(auth_token)), json=data)
assert response.status_code == 201
scopeusr = scope_name_generator()
response = rest_client.post('/accounts/%s/scopes/%s' % (acntusr, scopeusr), headers=headers(auth(auth_token)))
assert response.status_code == 201
response = rest_client.post('/accounts/%s/scopes/%s' % (acntusr, scopeusr), headers=headers(auth(auth_token)))
assert response.status_code == 409
def test_list_scope(rest_client, auth_token):
""" SCOPE (REST): send a GET list all scopes for one account """
tmp_val = account_name_generator()
headers_dict = {'Rucio-Type': 'user', 'X-Rucio-Account': 'root'}
data = {'type': 'USER', 'email': '[email protected]'}
response = rest_client.post('/accounts/%s' % tmp_val, headers=headers(auth(auth_token), hdrdict(headers_dict)), json=data)
assert response.status_code == 201
scopes = [scope_name_generator() for _ in range(5)]
for scope in scopes:
response = rest_client.post('/accounts/%s/scopes/%s' % (tmp_val, scope), headers=headers(auth(auth_token)), json={})
assert response.status_code == 201
response = rest_client.get('/accounts/%s/scopes/' % tmp_val, headers=headers(auth(auth_token)))
assert response.status_code == 200
svr_list = loads(response.get_data(as_text=True))
for scope in scopes:
assert scope in svr_list
def test_scope_change_ownership(rest_client, auth_token, random_account_factory):
""" SCOPE (REST): Send a post to change the existing scope's owner """
og_owner = random_account_factory()
scope = scope_name_generator()
response = rest_client.post(f'/accounts/{og_owner}/scopes/{scope}', headers=headers(auth(auth_token)))
assert response.status_code == 201
new_owner = random_account_factory()
response = rest_client.put(f"/scopes/{new_owner}/{scope}", headers=headers(auth(auth_token)))
assert response.status_code == 201
# Try to do it without sufficient permissions
new_owner = random_account_factory()
response = rest_client.put(f"/scopes/{new_owner}/{scope}", headers=headers(auth("fake_token")))
assert response.status_code == 401
# Try it with an account that doesn't exist
new_owner = account_name_generator()
response = rest_client.put(f"/scopes/{new_owner}/{scope}", headers=headers(auth(auth_token)))
assert response.status_code == 404
# try with a scope that doesn't exist
fake_scope = generate_uuid()
response = rest_client.put(f"/scopes/{random_account_factory()}/{fake_scope}", headers=headers(auth(auth_token)))
assert response.status_code == 404
def test_list_scope_account_not_found(rest_client, auth_token):
""" SCOPE (REST): send a GET list all scopes for a not existing account """
response = rest_client.get('/accounts/testaccount/scopes/', headers=headers(auth(auth_token)))
assert response.status_code == 404
assert response.headers.get('ExceptionClass') == 'AccountNotFound'
def test_list_scope_no_scopes(rest_client, auth_token):
""" SCOPE (REST): send a GET list all scopes for one account without scopes """
acntusr = account_name_generator()
data = {'type': 'USER', 'email': '[email protected]'}
response = rest_client.post('/accounts/' + acntusr, headers=headers(auth(auth_token)), json=data)
assert response.status_code == 201
response = rest_client.get('/accounts/%s/scopes/' % acntusr, headers=headers(auth(auth_token)))
assert response.status_code == 404
assert response.headers.get('ExceptionClass') == 'ScopeNotFound'
def test_list_scope_with_owner(rest_client, auth_token, scope_factory, vo, jdoe_account):
_, [scope] = scope_factory(vos=[vo], account_name=jdoe_account.external)
response = rest_client.get("/scopes/owner/", headers=headers(auth(auth_token)))
assert response.status_code == 200
out = loads(response.get_data(as_text=True))
assert scope.external in [s['scope'] for s in out]
assert jdoe_account.external in [s['account'] for s in out]
class TestScopeClient:
def test_create_scope(self, rucio_client):
""" SCOPE (CLIENTS): create a new scope."""
account = 'jdoe'
scope = scope_name_generator()
ret = rucio_client.add_scope(account, scope)
assert ret
with pytest.raises(InvalidObject):
rucio_client.add_scope(account, 'tooooolooooongscooooooooooooope')
with pytest.raises(InvalidObject):
rucio_client.add_scope(account, '$?!')
def test_create_scope_no_account(self, rucio_client):
""" SCOPE (CLIENTS): try to create scope for not existing account."""
account = str(uuid()).lower()[:30]
scope = scope_name_generator()
with pytest.raises(AccountNotFound):
rucio_client.add_scope(account, scope)
def test_create_scope_duplicate(self, rucio_client):
""" SCOPE (CLIENTS): try to create a duplicate scope."""
account = 'jdoe'
scope = scope_name_generator()
rucio_client.add_scope(account, scope)
with pytest.raises(Duplicate):
rucio_client.add_scope(account, scope)
def test_list_scopes(self, rucio_client):
""" SCOPE (CLIENTS): try to list scopes for an account."""
account = 'jdoe'
scope_list = [scope_name_generator() for _ in range(5)]
for scope in scope_list:
rucio_client.add_scope(account, scope)
svr_list = rucio_client.list_scopes_for_account(account)
for scope in scope_list:
if scope not in svr_list:
assert False
def test_list_scopes_account_not_found(self, rucio_client):
""" SCOPE (CLIENTS): try to list scopes for a non existing account."""
account = account_name_generator()
with pytest.raises(AccountNotFound):
rucio_client.list_scopes_for_account(account)
def test_list_scopes_no_scopes(self, rucio_client):
""" SCOPE (CLIENTS): try to list scopes for an account without scopes."""
account = account_name_generator()
rucio_client.add_account(account, 'USER', '[email protected]')
with pytest.raises(ScopeNotFound):
rucio_client.list_scopes_for_account(account)
def test_update_scope(self, rucio_client, scope_factory, random_account_factory, vo):
_, [scope] = scope_factory(vos=[vo])
new_account = random_account_factory()
with db_session(DatabaseOperationType.READ) as session:
is_not_owner = not is_scope_owner(scope, new_account, session)
assert is_not_owner
not_real_scope = generate_uuid()
with pytest.raises(ScopeNotFound):
rucio_client.update_scope(account=new_account.external, scope=not_real_scope)
not_real_account = generate_uuid()
with pytest.raises(AccountNotFound):
rucio_client.update_scope(account=not_real_account, scope=scope.external)
rucio_client.update_scope(account=new_account.external, scope=scope.external)
with db_session(DatabaseOperationType.READ) as session:
is_owner = is_scope_owner(scope, new_account, session)
assert is_owner
def test_list_scope_with_owner(self, rucio_client, scope_factory, jdoe_account, vo):
_, [scope] = scope_factory(vos=[vo], account_name=jdoe_account.external)
response = rucio_client.list_scope_owners()
assert isinstance(response, list)
assert isinstance(response[0], dict)
assert scope.external in [s['scope'] for s in response]
assert jdoe_account.external in [s['account'] for s in response]