Skip to content

Commit e706da8

Browse files
author
Abhishek Kumar
committed
Ranger REST API SmokeTests with ROBOT Framework
1 parent 651dcf2 commit e706da8

File tree

7 files changed

+454
-8
lines changed

7 files changed

+454
-8
lines changed

.github/workflows/maven.yml

+38-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
distribution: 'temurin'
4343
cache: maven
4444
- name: build (8)
45-
run: mvn -T 8 clean install --no-transfer-progress -B -V
45+
run: mvn -T 8 clean install -DskipTests --no-transfer-progress -B -V
4646
- name: Upload artifacts
4747
uses: actions/upload-artifact@v4
4848
with:
@@ -66,11 +66,10 @@ jobs:
6666
with:
6767
name: target-11
6868
path: target/*
69-
69+
7070
docker-build:
7171
needs:
7272
- build-8
73-
- build-11
7473
runs-on: ubuntu-latest
7574
steps:
7675
- uses: actions/checkout@v4
@@ -137,7 +136,8 @@ jobs:
137136
-f docker-compose.ranger-hive.yml \
138137
-f docker-compose.ranger-knox.yml \
139138
-f docker-compose.ranger-ozone.yml up -d
140-
- name: Check status of containers and remove them
139+
140+
- name: Check status of containers
141141
run: |
142142
sleep 60
143143
containers=(ranger ranger-zk ranger-solr ranger-postgres ranger-usersync ranger-tagsync ranger-kms ranger-hadoop ranger-hbase ranger-kafka ranger-hive ranger-knox ozone-om ozone-scm ozone-datanode);
@@ -153,8 +153,38 @@ jobs:
153153
154154
if [[ $flag == true ]]; then
155155
echo "All required containers are up and running";
156-
docker stop $(docker ps -q) && docker rm $(docker ps -aq);
157-
else
158-
docker stop $(docker ps -q) && docker rm $(docker ps -aq);
159-
exit 1;
160156
fi
157+
158+
- name: Set up Python
159+
uses: actions/setup-python@v4
160+
with:
161+
python-version: '3.9'
162+
163+
# Install Robot Framework and dependencies
164+
- name: Install Robot Framework
165+
run: |
166+
python -m pip install --upgrade pip
167+
python --version
168+
pip install apache-ranger
169+
pip install robotframework
170+
pip install robotframework-requests
171+
pip install robotframework-jsonlibrary
172+
robot --version || true
173+
174+
- name: Run Ranger REST API SmokeTests
175+
run: |
176+
cd dev-support/smoketests/ranger
177+
mkdir -p /tmp/smoketests/ranger
178+
robot --outputdir /tmp/smoketests/ranger --loglevel DEBUG -P apitests policy_management.robot user_management.robot
179+
180+
- name: Upload Robot Framework Test Result Artifacts
181+
if: always()
182+
uses: actions/upload-artifact@v4
183+
with:
184+
name: Robot-Framework-Artifacts
185+
path: /tmp/smoketests/ranger
186+
187+
- name: Remove Containers
188+
if: always()
189+
run: |
190+
docker stop $(docker ps -q) && docker rm $(docker ps -aq);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env python
2+
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more
5+
# contributor license agreements. See the NOTICE file distributed with
6+
# this work for additional information regarding copyright ownership.
7+
# The ASF licenses this file to You under the Apache License, Version 2.0
8+
# (the "License"); you may not use this file except in compliance with
9+
# the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python
2+
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more
5+
# contributor license agreements. See the NOTICE file distributed with
6+
# this work for additional information regarding copyright ownership.
7+
# The ASF licenses this file to You under the Apache License, Version 2.0
8+
# (the "License"); you may not use this file except in compliance with
9+
# the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
from apache_ranger.model.ranger_service import *
20+
from apache_ranger.client.ranger_client import *
21+
from apache_ranger.model.ranger_policy import *
22+
23+
24+
class TestPolicyManagement:
25+
ROBOT_LIBRARY_SCOPE = 'SUITE'
26+
27+
def __init__(self, ranger_url, username, password):
28+
self.ranger = RangerClient(ranger_url, (username, password))
29+
self.login_user = username
30+
self.ranger.session.verify = False
31+
self.test_hive_policy_prefix = 'test_hive_policy'
32+
self.test_hive_db_prefix = 'test_hive_db'
33+
self.test_hive_table_prefix = 'test_hive_table'
34+
return
35+
36+
def get_hive_policy(self, service_name, policy_name):
37+
return self.ranger.get_policy(service_name, policy_name)
38+
39+
def delete_hive_policy(self, service_name, policy_name):
40+
return self.ranger.delete_policy(service_name, policy_name)
41+
42+
@staticmethod
43+
def _create_policy_item_accesses(access_types):
44+
ret = []
45+
for access_type in access_types:
46+
ret.append(RangerPolicyItemAccess({'type': access_type}))
47+
return ret
48+
49+
@staticmethod
50+
def _create_policy_item(users, access_types):
51+
allow_item = RangerPolicyItem()
52+
allow_item.users = users
53+
allow_item.accesses = TestPolicyManagement._create_policy_item_accesses(access_types)
54+
return allow_item
55+
56+
@staticmethod
57+
def _create_policy_item_with_delegate_admin(users, access_types):
58+
allow_item = TestPolicyManagement._create_policy_item(users, access_types)
59+
allow_item.delegateAdmin = True
60+
return allow_item
61+
62+
@staticmethod
63+
def _create_hive_policy_resource(db_name, table_name, column_name):
64+
resources = {
65+
'database': RangerPolicyResource({'values': [db_name]}),
66+
'table': RangerPolicyResource({'values': [table_name]}),
67+
'column': RangerPolicyResource({'values': [column_name]})
68+
}
69+
return resources
70+
71+
def create_hive_policy(self, service_name, policy_name, db_name, table_name):
72+
policy = RangerPolicy()
73+
policy.service = service_name
74+
policy.name = policy_name
75+
policy.resources = TestPolicyManagement._create_hive_policy_resource(db_name, table_name, "*")
76+
allow_item = TestPolicyManagement._create_policy_item_with_delegate_admin(['test_user_1'], ['create', 'alter'])
77+
deny_item = TestPolicyManagement._create_policy_item([self.login_user], ['drop'])
78+
policy.policyItems = [allow_item]
79+
policy.denyPolicyItems = [deny_item]
80+
81+
created_policy = self.ranger.create_policy(policy)
82+
print(f'Created policy: name={created_policy.name}, id={created_policy.id}')
83+
return created_policy
84+
85+
def get_all_policies(self):
86+
all_policies = self.ranger.find_policies()
87+
return all_policies
88+
89+
def create_policies_in_bulk(self, service_name, count):
90+
count = int(count)
91+
for i in range(count):
92+
policy_name = f'{self.test_hive_policy_prefix}_{i}'
93+
db_name = f'{self.test_hive_db_prefix}_{i}'
94+
table_name = f'{self.test_hive_table_prefix}_{i}'
95+
self.create_hive_policy(service_name, policy_name, db_name, table_name)
96+
return
97+
98+
def delete_policies_in_bulk(self, service_name, count):
99+
count = int(count)
100+
for i in range(count):
101+
policy_name = f'{self.test_hive_policy_prefix}_{i}'
102+
self.delete_hive_policy(service_name, policy_name)
103+
return
104+
105+
106+
class TestServiceManagement:
107+
ROBOT_LIBRARY_SCOPE = 'SUITE'
108+
109+
def __init__(self, ranger_url, username, password):
110+
self.ranger = RangerClient(ranger_url, (username, password))
111+
self.ranger.session.verify = False
112+
return
113+
114+
def create_service(self, service_name, service_type, configs):
115+
service = RangerService()
116+
service.name = service_name
117+
service.type = service_type
118+
service.configs = configs
119+
return self.ranger.create_service(service)
120+
121+
def delete_service(self, service_name):
122+
return self.ranger.delete_service(service_name)
123+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env python
2+
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more
5+
# contributor license agreements. See the NOTICE file distributed with
6+
# this work for additional information regarding copyright ownership.
7+
# The ASF licenses this file to You under the Apache License, Version 2.0
8+
# (the "License"); you may not use this file except in compliance with
9+
# the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
from apache_ranger.client.ranger_client import *
20+
from apache_ranger.utils import *
21+
from apache_ranger.model.ranger_user_mgmt import *
22+
from apache_ranger.client.ranger_user_mgmt_client import *
23+
24+
25+
class TestUserManagement:
26+
def __init__(self, ranger_url, username, password):
27+
self.ranger = RangerClient(ranger_url, (username, password))
28+
self.ranger.session.verify = False
29+
self.ugclient = RangerUserMgmtClient(self.ranger)
30+
return
31+
32+
ROBOT_LIBRARY_SCOPE = 'SUITE'
33+
34+
def find_users(self):
35+
print('Listing all users!')
36+
users = self.ugclient.find_users()
37+
print(f'{len(users.list)} users found')
38+
return users
39+
40+
def find_groups(self):
41+
print('Listing all groups!')
42+
groups = self.ugclient.find_groups()
43+
print(f'{len(groups.list)} groups found')
44+
return groups
45+
46+
def create_user(self, user_name, role):
47+
user = RangerUser({'name': user_name,
48+
'firstName': user_name,
49+
'lastName': 'lnu',
50+
'emailAddress': user_name + '@test.org',
51+
'password': 'Welcome1',
52+
'userRoleList': [role],
53+
'otherAttributes': '{ "dept": "test" }'})
54+
55+
created_user = self.ugclient.create_user(user)
56+
print(f'User {created_user.name} created!')
57+
return created_user
58+
59+
def create_group(self, group_name):
60+
group = RangerGroup({'name': group_name, 'otherAttributes': '{ "dept": "test" }'})
61+
created_group = self.ugclient.create_group(group)
62+
print(f'Group {created_group.name} created!')
63+
return created_group
64+
65+
def add_to_group(self, group_name, group_id, user_id):
66+
group_user = RangerGroupUser({'name': group_name, 'parentGroupId': group_id, 'userId': user_id})
67+
created_group_user = self.ugclient.create_group_user(group_user)
68+
print(f'Created group-user: {created_group_user}')
69+
return created_group_user
70+
71+
def list_users_in_group(self, group_name):
72+
users = self.ugclient.get_users_in_group(group_name)
73+
return users
74+
75+
def list_groups_for_user(self, user_name):
76+
groups = self.ugclient.get_groups_for_user(user_name)
77+
return groups
78+
79+
def list_group_users(self):
80+
group_users = self.ugclient.find_group_users()
81+
print(f'{len(group_users.list)} group-users found')
82+
83+
for group_user in group_users.list:
84+
print(f'id: {group_user.id}, groupId: {group_user.parentGroupId}, userId: {group_user.userId}')
85+
return group_users
86+
87+
def delete_user_by_id(self, id):
88+
self.ugclient.delete_user_by_id(id, True)
89+
return
90+
91+
def delete_group_by_id(self, id):
92+
self.ugclient.delete_group_by_id(id, True)
93+
return
94+
95+
def delete_group_user_by_id(self, id):
96+
self.ugclient.delete_group_user_by_id(id)
97+
return
98+
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
*** Settings ***
2+
Library policy_management.TestPolicyManagement http://localhost:6080 admin rangerR0cks! WITH NAME admin_p
3+
Library policy_management.TestPolicyManagement http://localhost:6080 test_user_1 Welcome1 WITH NAME user_t
4+
Library policy_management.TestPolicyManagement http://localhost:6080 finance_user Welcome1 WITH NAME user_f
5+
Library Collections
6+
Library JSONLibrary
7+
8+
*** Variables ***
9+
10+
11+
*** Test Cases ***
12+
Admin User Succeeds To Create Policy Regular User Fails
13+
[Documentation] A regular user fails to create hive policy whereas an admin user succeeds.
14+
${response} admin_p.Create Hive Policy dev_hive test_policy_custom_1 test_db_custom_1 test_table_custom_1
15+
Log ${response}
16+
Run Keyword And Expect Error RangerServiceException* user_t.Create Hive Policy dev_hive test_policy_custom_2 test_db_custom_2 test_table_custom_2
17+
18+
19+
Regular User With Delegate-Admin Succeeds To Delete Policy Where Regular User Fails
20+
[Documentation] A regular user with delegated-admin succeeds to delete hive policy whereas a regular user w/o delegated-admin fails
21+
Run Keyword And Expect Error RangerServiceException* user_f.Delete Hive Policy dev_hive test_policy_custom_1
22+
${response} user_t.Delete Hive Policy dev_hive test_policy_custom_1
23+
Log ${response}

0 commit comments

Comments
 (0)