Skip to content

Commit e6102bf

Browse files
author
Abhishek Kumar
committed
Ranger REST API SmokeTests with ROBOT Framework
1 parent f06d0e7 commit e6102bf

File tree

6 files changed

+380
-8
lines changed

6 files changed

+380
-8
lines changed

.github/workflows/maven.yml

+36-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
@@ -134,7 +133,8 @@ jobs:
134133
-f docker-compose.ranger-hive.yml \
135134
-f docker-compose.ranger-knox.yml \
136135
-f docker-compose.ranger-ozone.yml up -d
137-
- name: Check status of containers and remove them
136+
137+
- name: Check status of containers
138138
run: |
139139
sleep 60
140140
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);
@@ -150,8 +150,36 @@ jobs:
150150
151151
if [[ $flag == true ]]; then
152152
echo "All required containers are up and running";
153-
docker stop $(docker ps -q) && docker rm $(docker ps -aq);
154-
else
155-
docker stop $(docker ps -q) && docker rm $(docker ps -aq);
156-
exit 1;
157153
fi
154+
155+
- name: Set up Python
156+
uses: actions/setup-python@v4
157+
with:
158+
python-version: '3.9'
159+
160+
# Install Robot Framework and dependencies
161+
- name: Install Robot Framework
162+
run: |
163+
python -m pip install --upgrade pip
164+
python --version
165+
pip install apache-ranger
166+
pip install robotframework
167+
pip install robotframework-requests
168+
pip install robotframework-jsonlibrary
169+
robot --version || true
170+
171+
- name: Run Ranger REST API SmokeTests
172+
run: |
173+
cd dev-support/smoketests/ranger
174+
mkdir -p /tmp/smoketests/ranger
175+
robot --outputdir /tmp/smoketests/ranger --loglevel DEBUG -P apitests policy_management.robot user_management.robot
176+
177+
- name: Upload Robot Framework Test Result Artifacts
178+
uses: actions/upload-artifact@v4
179+
with:
180+
name: Robot-Framework-Artifacts
181+
path: /tmp/smoketests/ranger
182+
183+
- name: Remove Containers
184+
run: |
185+
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,87 @@
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.ranger.session.verify = False
30+
return
31+
32+
def get_hive_policy(self, service_name, policy_name):
33+
return self.ranger.get_policy(service_name, policy_name)
34+
35+
def delete_hive_policy(self, service_name, policy_name):
36+
return self.ranger.delete_policy(service_name, policy_name)
37+
38+
def create_hive_policy(self, service_name, policy_name, db_name):
39+
policy = RangerPolicy()
40+
policy.service = service_name
41+
policy.name = policy_name
42+
policy.resources = {'database': RangerPolicyResource({'values': [db_name]}),
43+
'table': RangerPolicyResource({'values': ['test_tbl']}),
44+
'column': RangerPolicyResource({'values': ['*']})}
45+
46+
allowItem1 = RangerPolicyItem()
47+
allowItem1.users = ['admin']
48+
allowItem1.accesses = [RangerPolicyItemAccess({'type': 'create'}),
49+
RangerPolicyItemAccess({'type': 'alter'})]
50+
51+
denyItem1 = RangerPolicyItem()
52+
denyItem1.users = ['admin']
53+
denyItem1.accesses = [RangerPolicyItemAccess({'type': 'drop'})]
54+
55+
policy.policyItems = [allowItem1]
56+
policy.denyPolicyItems = [denyItem1]
57+
58+
print(f'Creating policy: name={policy.name}')
59+
60+
created_policy = self.ranger.create_policy(policy)
61+
62+
print(f'Created policy: name={created_policy.name}, id={created_policy.id}')
63+
return created_policy
64+
65+
def get_all_policies(self):
66+
all_policies = self.ranger.find_policies()
67+
return all_policies
68+
69+
70+
class TestServiceManagement:
71+
ROBOT_LIBRARY_SCOPE = 'SUITE'
72+
73+
def __init__(self, ranger_url, username, password):
74+
self.ranger = RangerClient(ranger_url, (username, password))
75+
self.ranger.session.verify = False
76+
return
77+
78+
def create_service(self, service_name, service_type, configs):
79+
service = RangerService()
80+
service.name = service_name
81+
service.type = service_type
82+
service.configs = configs
83+
return self.ranger.create_service(service)
84+
85+
def delete_service(self, service_name):
86+
return self.ranger.delete_service(service_name)
87+
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):
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_USER'],
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+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
*** Settings ***
2+
Library policy_management.TestPolicyManagement http://localhost:6080 admin rangerR0cks!
3+
Library policy_management.TestServiceManagement http://localhost:6080 admin rangerR0cks!
4+
Library Collections
5+
Library JSONLibrary
6+
7+
*** Variables ***
8+
${HIVE_DEFAULT_SVC} dev_hive
9+
${HIVE_DEFAULT_POLICY} all - global
10+
${HIVE_TEST_SVC} test_hive
11+
${HIVE_TEST_POLICY} test_policy
12+
@{TEST_DB} test_db
13+
14+
*** Test Cases ***
15+
Create Hive Test Service
16+
[Documentation] Create a test Hive service with specific configurations.
17+
${configs} Create Dictionary username=hive password=hive jdbc.driverClassName=org.apache.hive.jdbc.HiveDriver jdbc.url=jdbc:hive2://ranger-hadoop:10000 hadoop.security.authorization=${true}
18+
${response} Create Service test_hive hive ${configs}
19+
Log ${response}
20+
21+
22+
Delete Hive Test Service
23+
[Documentation] Delete the test Hive service.
24+
${response} Delete Service ${HIVE_TEST_SVC}
25+
26+
27+
Get All Policies
28+
[Documentation] Get all policies in Ranger.
29+
${response} Get All Policies
30+
${service} Get Value From Json ${response} $[0].service
31+
Should Be Equal ${service}[0] dev_hdfs
32+
33+
34+
Validate Response - Get Default Hive Policy
35+
[Documentation] Validate Response from the default hive policy: all - global
36+
${response} Get Hive Policy ${HIVE_DEFAULT_SVC} ${HIVE_DEFAULT_POLICY}
37+
38+
${service} Get Value From Json ${response} $.service
39+
${name} Get Value From Json ${response} $.name
40+
${isEnabled} Get Value From Json ${response} $.isEnabled
41+
${users} Get Value From Json ${response} $.policyItems[0].users
42+
43+
Should Be Equal ${service}[0] ${HIVE_DEFAULT_SVC}
44+
Should Be Equal ${name}[0] ${HIVE_DEFAULT_POLICY}
45+
Should Be True ${isEnabled}
46+
List Should Contain Value ${users}[0] hive
47+
Log ${response}
48+
49+
50+
Create Hive Test Policy
51+
[Documentation] Create a test policy in Default Hive Service
52+
${response} Create Hive Policy dev_hive test_policy_78 test_db
53+
54+
${id} Get Value From Json ${response} $.id
55+
Set Suite Variable ${POLICY_ID} ${id}
56+
Log ${response}
57+
58+
59+
Delete Hive Test Policy
60+
${response} Delete Hive Policy dev_hive test_policy_78
61+
Log ${response}
62+
63+
# Depends on an earlier Test
64+
Validate Successive Hive Test Policy
65+
[Documentation] Create the test policy again in Default Hive Service
66+
${response} Create Hive Policy dev_hive test_policy_78 test_db
67+
68+
${id} Get Value From Json ${response} $.id
69+
${result} Evaluate ${POLICY_ID}[0] + 1
70+
Should Be Equal ${id}[0] ${result}
71+
Log ${response}
72+
73+
74+
Delete Successive Hive Test Policy
75+
${response} Delete Hive Policy dev_hive test_policy_78
76+
Log ${response}
77+
78+
79+
Create 100 Policies
80+
FOR ${i} IN RANGE 1 101
81+
${policy_name} Create Hive Policy dev_hive policy_${i} test_db_${i}
82+
Log Created policy: ${policy_name}
83+
END
84+
85+
86+
Delete 100 Policies
87+
FOR ${i} IN RANGE 1 101
88+
Delete Hive Policy ${HIVE_DEFAULT_SVC} policy_${i}
89+
END

0 commit comments

Comments
 (0)