[DCAEGEN2] PMSH Update Administrative status for measurement group automation
[integration/csit.git] / tests / dcaegen2-services-pmsh / testcases / pmsh.robot
1 *** Settings ***
2 Documentation     Testing PMSH functionality
3
4 Library           OperatingSystem
5 Library           RequestsLibrary
6 Library           String
7 Library           Process
8
9 Resource          ../../common.robot
10 Test Teardown     Delete All Sessions
11
12
13 *** Variables ***
14
15 ${PMSH_BASE_URL}                    https://${PMSH_IP}:8443
16 ${MR_BASE_URL}                      http://${MR_IP_ADDRESS}:3904
17 ${CBS_BASE_URL}                     https://${CBS_SIM_IP_ADDRESS}:10443
18 ${SUBSCRIPTION_ENDPOINT}            /subscription
19 ${POLICY_PUBLISH_MR_TOPIC}          /events/unauthenticated.PMSH_CL_INPUT
20 ${AAI_MR_TOPIC}                     /events/AAI_EVENT
21
22 ${MR_AAI_PNF_CREATED}                       %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/aai-pnf-create.json
23 ${MR_AAI_PNF_REMOVED}                       %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/aai-pnf-delete.json
24 ${MR_POLICY_RESPONSE_PNF_EXISTING}          %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/policy-sub-created-pnf-existing.json
25 ${MR_POLICY_RESPONSE_PNF_DELETED}           %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/policy-sub-deleted-pnf-existing.json
26 ${CBS_EXPECTATION_ADMIN_STATE_UNLOCKED}     %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/cbs-expectation-unlocked-config.json
27 ${CREATE_SUBSCRIPTION_DATA}                 %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/create_subscription_request.json
28 ${CREATE_SECOND_SUBSCRIPTION_DATA}          %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/create_second_subscription_request.json
29 ${CREATE_SUBSCRIPTION_BAD_DATA}             %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/create_subscription_bad_request.json
30 ${CREATE_SUBSCRIPTION_SCHEMA_ERROR_DATA}    %{WORKSPACE}/tests/dcaegen2-services-pmsh/testcases/assets/create_subscription_schema_error_request.json
31 ${ADMIN_STATE_LOCKED_PATTERN}       'administrativeState': 'LOCKED'
32 ${CLI_EXEC_GET_CBS_CONFIG_FIRST}    docker exec pmsh /bin/sh -c "grep -m 1 'PMSH config from CBS' /var/log/ONAP/dcaegen2/services/pmsh/application.log"
33
34 *** Test Cases ***
35 Verify Get subscriptions with Network Functions None
36     [Tags]                          PMSH_01
37     [Documentation]                 Verify Get all subscriptions when there are no defined subscriptions
38     [Timeout]                       10 seconds
39     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}     ""
40     Should Be True                  ${resp.status_code} == 200
41     Should Contain                  ${resp.text}                     []
42
43 Verify Create Subscriptions API
44     [Tags]                          PMSH_07
45     [Documentation]                 Verify Create Subscription API
46     [Timeout]                       60 seconds
47     ${json_value}=                  json_from_file                  ${CREATE_SUBSCRIPTION_DATA}
48     ${resp}=                        PostSubscriptionCall     ${SUBSCRIPTION_ENDPOINT}   ${json_value}
49     Should Be True                  ${resp.status_code} == 201
50      ${resp}=                       GetSubsCall    ${SUBSCRIPTION_ENDPOINT}   "/subs_01"
51     Should Be Equal As Strings      ${resp.json()[0]['subscription']['subscriptionName']}       subs_01
52
53 Verify database tables exist and are empty
54     [Tags]                          PMSH_02
55     [Documentation]                 Verify database has been created and is empty
56     [Timeout]                       10 seconds
57     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}     ""
58     Should Be True                  ${resp.status_code} == 200
59     Should Contain                  ${resp.text}                     []
60
61 Verify PNF detected in AAI when administrative state unlocked
62     [Tags]                          PMSH_03
63     [Documentation]                 Verify PNF detected when administrative state unlocked
64     [Timeout]                       60 seconds
65     SetAdministrativeStateToUnlocked
66     Sleep                           31             Allow PMSH time to pick up changes in CBS config
67     ${resp}=                        GetMeasGrpCall    /subscription/subs_01/measurementGroups/msg_grp_01
68     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
69     Should Be Equal As Strings      ${resp.json()['administrativeState']}       UNLOCKED
70     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}            pnf-existing
71     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfMgStatus']}      PENDING_CREATE
72
73 Verify Policy response on MR is handled
74     [Tags]                          PMSH_04
75     [Documentation]                 Verify policy response on MR is handled
76     [Timeout]                       60 seconds
77     SimulatePolicyResponse          ${MR_POLICY_RESPONSE_PNF_EXISTING}
78     Sleep                           31 seconds      Ensure Policy response on MR is picked up
79     ${resp}=                        GetMeasGrpCall    /subscription/subs_01/measurementGroups/msg_grp_01
80     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
81     Should Be Equal As Strings      ${resp.json()['administrativeState']}       UNLOCKED
82     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}            pnf-existing
83     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfMgStatus']}     CREATED
84
85 Verify AAI event on MR detailing new PNF being detected is handled
86     [Tags]                          PMSH_05
87     [Documentation]                 Verify PNF created AAI event on MR is handled
88     [Timeout]                       60 seconds
89     SimulateNewPNF                  ${MR_AAI_PNF_CREATED}
90     Sleep                           31 seconds      Ensure AAI event on MR is picked up
91     ${resp}=                        GetMeasGrpCall    /subscription/subs_01/measurementGroups/msg_grp_01
92     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
93     Should Be Equal As Strings      ${resp.json()['administrativeState']}       UNLOCKED
94     Should Be Equal As Strings      ${resp.json()['networkFunctions'][1]['nfName']}            pnf_newly_discovered
95     Should Be Equal As Strings      ${resp.json()['networkFunctions'][1]['nfMgStatus']}      PENDING_CREATE
96
97 Verify AAI event on MR detailing PNF being deleted is handled
98     [Tags]                          PMSH_06
99     [Documentation]                 Verify PNF deleted AAI event on MR is handled
100     [Timeout]                       60 seconds
101     SimulateDeletedPNF              ${MR_AAI_PNF_REMOVED}
102     Sleep                           31 seconds      Ensure AAI event on MR is picked up
103     ${resp}=                        GetMeasGrpCall    /subscription/subs_01/measurementGroups/msg_grp_01
104     Should Not Contain              ${resp.text}    pnf_newly_discovered
105
106 Verify Create Subscription API for duplicate subscription Id
107     [Tags]                          PMSH_08
108     [Documentation]                 Verify Create Subscription API for duplicate subscription Id
109     [Timeout]                       60 seconds
110     ${json_value}=                  json_from_file                  ${CREATE_SUBSCRIPTION_DATA}
111     ${resp}=                        PostSubscriptionCall     ${SUBSCRIPTION_ENDPOINT}   ${json_value}
112     Should Be True                  ${resp.status_code} == 409
113     Should Contain                  ${resp.json()}      subscription Name: subs_01 already exists.
114
115 Verify Create Subscription API for schema error
116     [Tags]                          PMSH_09
117     [Documentation]                 Verify Create Subscription API
118     [Timeout]                       60 seconds
119     ${json_value}=                  json_from_file                  ${CREATE_SUBSCRIPTION_SCHEMA_ERROR_DATA}
120     ${resp}=                        PostSubscriptionCall     ${SUBSCRIPTION_ENDPOINT}   ${json_value}
121     Should Be True                  ${resp.status_code} == 400
122     Should Contain                  ${resp.json()['detail']}      'administrativeState' is a required property - 'subscription.measurementGroups.0.measurementGroup'
123
124 Verify Create Subscription API for filter values missing
125     [Tags]                          PMSH_10
126     [Documentation]                 Verify Create Subscription API
127     [Timeout]                       60 seconds
128     ${json_value}=                  json_from_file                  ${CREATE_SUBSCRIPTION_BAD_DATA}
129     ${resp}=                        PostSubscriptionCall     ${SUBSCRIPTION_ENDPOINT}   ${json_value}
130     Should Be True                  ${resp.status_code} == 400
131     Should Contain                  ${resp.json()}      At least one filter within nfFilter must not be empty
132
133 Verify Get Measurement Group with Network Functions
134     [Tags]                          PMSH_11
135     [Documentation]                 Verify Get Measurement Group with Network Functions by using MGName and SubName
136     [Timeout]                       60 seconds
137     ${resp}=                        GetMeasGrpWithNFSCall     /subscription/subs_01/measurementGroups/msg_grp_01
138     ${nf_length}=                   Get length  ${resp.json()['networkFunctions']}
139     Should Be True                  ${resp.status_code} == 200
140     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
141     Should Be Equal As Strings      ${resp.json()['measurementGroupName']}      msg_grp_01
142     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}      pnf-existing
143     Should be equal as numbers      ${nf_length}  1
144
145 Verify Get single subscription with Network Functions
146     [Tags]                          PMSH_12
147     [Documentation]                 Verify Get single subscription with Network Functions by using subscription name
148     [Timeout]                       60 seconds
149     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}/subs_01  ""
150     ${nf_length}=                   Get length  ${resp.json()['subscription']['nfs']}
151     Should Be True                  ${resp.status_code} == 200
152     Should Be Equal As Strings      ${resp.json()['subscription']['subscriptionName']}      subs_01
153     Should Be Equal As Strings      ${resp.json()['subscription']['nfs'][0]}      pnf-existing
154         Should Be Equal As Strings      ${resp.json()['subscription']['measurementGroups'][0]['measurementGroup']['measurementGroupName']}  msg_grp_02
155     Should be equal as numbers      ${nf_length}  1
156
157 Verify Get single subscription with Network Functions None
158     [Tags]                          PMSH_13
159     [Documentation]                 Verify Get single subscription with Network Functions when there is no defined subscription
160     [Timeout]                       60 seconds
161     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}/sub_none  ""
162     Should Be True                  ${resp.status_code} == 404
163     Should Be Equal As Strings      ${resp.json()['error']}     Subscription was not defined with the name : sub_none
164
165 Verify Update Measurement Group admin status from Unlocked to Locking
166     [Tags]                          PMSH_14
167     [Documentation]                 Verify Update Measurement Group admin status from Unlocked to Locking
168     [Timeout]                       60 seconds
169     ${json_string}=                 Set Variable    {"administrativeState": "LOCKED"}
170     ${json}=                        evaluate        json.loads('''${json_string}''')    json
171     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_01/adminState   ${json}
172     Should Be True                  ${resp.status_code} == 200
173     Should Contain                  ${resp.json()}      Successfully updated admin state
174     ${resp}=                        GetMeasGrpWithNFSCall     /subscription/subs_01/measurementGroups/msg_grp_01
175     ${nf_length}=                   Get length  ${resp.json()['networkFunctions']}
176     Should Be True                  ${resp.status_code} == 200
177     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
178     Should Be Equal As Strings      ${resp.json()['measurementGroupName']}      msg_grp_01
179     Should Be Equal As Strings      ${resp.json()['administrativeState']}       LOCKING
180     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}      pnf-existing
181     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfMgStatus']}      PENDING_DELETE
182     Should be equal as numbers      ${nf_length}  1
183
184 Verify Update Measurement Group admin status with locking in progress
185     [Tags]                          PMSH_15
186     [Documentation]                 Verify Update Measurement Group admin status with locking in progress
187     [Timeout]                       60 seconds
188     ${json_string}=                 Set Variable    {"administrativeState": "LOCKED"}
189     ${json}=                        evaluate        json.loads('''${json_string}''')    json
190     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_01/adminState   ${json}
191     Should Be True                  ${resp.status_code} == 409
192     Should Contain                  ${resp.json()}  Cannot update admin status as Locked request is in progress for sub name: subs_01  and meas group name: msg_grp_01
193
194 Verify Measurement Group admin status update from Locking to Locked
195     [Tags]                          PMSH_16
196     [Documentation]                 Verify Measurement Group admin status update from Locking to Locked
197     [Timeout]                       60 seconds
198     SimulatePolicyResponse          ${MR_POLICY_RESPONSE_PNF_DELETED}
199     Sleep                           31 seconds      Ensure Policy response on MR is picked up
200     ${resp}=                        GetMeasGrpCall    /subscription/subs_01/measurementGroups/msg_grp_01
201     Should Be Equal As Strings      ${resp.json()['measurementGroupName']}      msg_grp_01
202     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
203     Should Be Equal As Strings      ${resp.json()['administrativeState']}       LOCKED
204     ${nf_length}=                   Get length  ${resp.json()['networkFunctions']}
205     Should be equal as numbers      ${nf_length}  0
206
207 Verify Update Measurement Group admin status to unlocked with no Network Functions in Subscription
208     [Tags]                          PMSH_17
209     [Documentation]                 Verify Update Measurement Group admin status to unlocked with no Network Functions in Subscription
210     [Timeout]                       60 seconds
211     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}/subs_01  ""
212     ${nf_length}=                   Get length  ${resp.json()['subscription']['nfs']}
213     Should be equal as numbers      ${nf_length}  0
214     ${json_string}=                 Set Variable    {"administrativeState": "UNLOCKED"}
215     ${json}=                        evaluate        json.loads('''${json_string}''')    json
216     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_01/adminState   ${json}
217     Should Be True                  ${resp.status_code} == 200
218     Should Contain                  ${resp.json()}      Successfully updated admin state
219     ${resp}=                        GetMeasGrpWithNFSCall     /subscription/subs_01/measurementGroups/msg_grp_01
220     ${nf_length}=                   Get length  ${resp.json()['networkFunctions']}
221     Should Be True                  ${resp.status_code} == 200
222     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
223     Should Be Equal As Strings      ${resp.json()['measurementGroupName']}      msg_grp_01
224     Should Be Equal As Strings      ${resp.json()['administrativeState']}       UNLOCKED
225     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}      pnf-existing
226     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfMgStatus']}      PENDING_CREATE
227     Should be equal as numbers      ${nf_length}  1
228
229 Verify Update Measurement Group admin status from Locked to Unlocked with Network function present in subscription
230     [Tags]                          PMSH_18
231     [Documentation]                 Verify Update Measurement Group admin status from Locked to Unlocked with Network function present in subscription
232     [Timeout]                       60 seconds
233     ${json_string}=                 Set Variable    {"administrativeState": "UNLOCKED"}
234     ${json}=                        evaluate        json.loads('''${json_string}''')    json
235     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_02/adminState   ${json}
236     Should Be True                  ${resp.status_code} == 200
237     Should Contain                  ${resp.json()}      Successfully updated admin state
238     ${resp}=                        GetMeasGrpWithNFSCall     /subscription/subs_01/measurementGroups/msg_grp_02
239     ${nf_length}=                   Get length  ${resp.json()['networkFunctions']}
240     Should Be True                  ${resp.status_code} == 200
241     Should Be Equal As Strings      ${resp.json()['subscriptionName']}      subs_01
242     Should Be Equal As Strings      ${resp.json()['measurementGroupName']}      msg_grp_02
243     Should Be Equal As Strings      ${resp.json()['administrativeState']}       UNLOCKED
244     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfName']}      pnf-existing
245     Should Be Equal As Strings      ${resp.json()['networkFunctions'][0]['nfMgStatus']}      PENDING_CREATE
246     Should be equal as numbers      ${nf_length}  1
247
248 Verify Update Measurement Group admin status with no change
249     [Tags]                          PMSH_19
250     [Documentation]                 Verify Update Measurement Group admin status with no change
251     [Timeout]                       60 seconds
252     ${json_string}=                 Set Variable    {"administrativeState": "UNLOCKED"}
253     ${json}=                        evaluate        json.loads('''${json_string}''')    json
254     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_01/adminState   ${json}
255     Should Be True                  ${resp.status_code} == 400
256     Should Contain                  ${resp.json()}  Measurement group is already in UNLOCKED state for sub name: subs_01  and meas group name: msg_grp_01
257
258 Verify Update Measurement Group admin status for invalid measurement group
259     [Tags]                          PMSH_20
260     [Documentation]                 Verify Update Measurement Group admin status for invalid measurement group
261     [Timeout]                       60 seconds
262     ${json_string}=                 Set Variable    {"administrativeState": "LOCKED"}
263     ${json}=                        evaluate        json.loads('''${json_string}''')    json
264     ${resp}=                        PutMsgGrpStatusCall     /subscription/subs_01/measurementGroups/msg_grp_11/adminState   ${json}
265     Should Be True                  ${resp.status_code} == 400
266     Should Contain                  ${resp.json()}  Requested measurement group not available for admin status update
267
268 Verify Get subscriptions with Network Functions
269     [Tags]                          PMSH_21
270     [Documentation]                 Verify Get subscriptions with Network Functions
271     [Timeout]                       60 seconds
272     ${json_value}=                  json_from_file                  ${CREATE_SECOND_SUBSCRIPTION_DATA}
273     ${resp_post}=                   PostSubscriptionCall     ${SUBSCRIPTION_ENDPOINT}   ${json_value}
274     ${resp}=                        GetSubsCall    ${SUBSCRIPTION_ENDPOINT}  ""
275     ${nf_length_first}=             Get length  ${resp.json()[0]['subscription']['nfs']}
276     ${nf_length_second}=            Get length  ${resp.json()[1]['subscription']['nfs']}
277     Should Be True                  ${resp.status_code} == 200
278     Should Be Equal As Strings      ${resp.json()[0]['subscription']['subscriptionName']}      subs_01
279     Should Be Equal As Strings      ${resp.json()[0]['subscription']['nfs'][0]}      pnf-existing
280         Should Be Equal As Strings      ${resp.json()[0]['subscription']['measurementGroups'][0]['measurementGroup']['measurementGroupName']}  msg_grp_02
281     Should be equal as numbers      ${nf_length_first}  1
282     Should Be Equal As Strings      ${resp.json()[1]['subscription']['subscriptionName']}      subs_02
283     Should Be Equal As Strings      ${resp.json()[1]['subscription']['nfs'][0]}      pnf-existing
284         Should Be Equal As Strings      ${resp.json()[1]['subscription']['measurementGroups'][0]['measurementGroup']['measurementGroupName']}  msg_grp_04
285     Should be equal as numbers      ${nf_length_second}  1
286
287 *** Keywords ***
288
289 SetAdministrativeStateToUnlocked
290     ${data}=            Get Data From File      ${CBS_EXPECTATION_ADMIN_STATE_UNLOCKED}
291     Create Session      cbs_sim_session   ${CBS_BASE_URL}    verify=false
292     ${resp}=            PUT On Session    cbs_sim_session    url=/clear  data={"path": "/service_component_all/.*"}
293     Should Be True      ${resp.status_code} == 200
294     Sleep               2                 Allow CBS time to set expectation
295     ${resp} =           PUT On Session    cbs_sim_session    url=/expectation     data=${data}
296     Should Be True      ${resp.status_code} == 201
297
298
299 SimulatePolicyResponse
300     [Arguments]                     ${expected_contents}
301     ${json_value}=                  json_from_file                  ${expected_contents}
302     ${resp}=                                            PostMrCall                                  ${POLICY_PUBLISH_MR_TOPIC}     ${json_value}
303     log                                                 ${resp.text}
304     Should Be Equal As Strings          ${resp.status_code}             200
305     ${count}=                           Evaluate                                        $resp.json().get('count')
306     log                                                         'JSON Response Code:'${resp}
307
308 SimulateNewPNF
309     [Arguments]                     ${expected_contents}
310     ${json_value}=                  json_from_file                  ${expected_contents}
311     ${resp}=                                            PostMrCall                                      ${AAI_MR_TOPIC}      ${json_value}
312     log                                                 ${resp.text}
313     Should Be Equal As Strings          ${resp.status_code}             200
314     ${count}=                           Evaluate                                        $resp.json().get('count')
315     log                                                         'JSON Response Code:'${resp}
316
317 SimulateDeletedPNF
318     [Arguments]                     ${expected_contents}
319     ${json_value}=                  json_from_file                  ${expected_contents}
320     ${resp}=                                            PostMrCall                                      ${AAI_MR_TOPIC}      ${json_value}
321     log                                                 ${resp.text}
322     Should Be Equal As Strings          ${resp.status_code}             200
323     ${count}=                           Evaluate                                        $resp.json().get('count')
324     log                                                         'JSON Response Code:'${resp}
325
326 PostMrCall
327     [Arguments]     ${url}     ${data}
328     Create Session  mr_sim_session       ${MR_BASE_URL}    verify=false
329     ${headers}=     Create Dictionary    Accept=application/json     Content-Type=application/json
330     ${resp}=        POST On Session      mr_sim_session    url=${url}    json=${data}     headers=${headers}
331     [Return]        ${resp}
332
333 GetSubsCall
334     [Arguments]     ${url}      ${url_path_param}
335     Create Session  pmsh_session      ${PMSH_BASE_URL}    verify=false
336     ${resp}=        GET On Session    pmsh_session        url=${url}    data={"path": {url_path_param}}    expected_status=any
337     [Return]        ${resp}
338
339 GetMeasGrpCall
340     [Arguments]     ${url}
341     Create Session  pmsh_session      ${PMSH_BASE_URL}    verify=false
342     ${resp}=        GET On Session    pmsh_session        url=${url}
343     [Return]        ${resp}
344
345 GetMeasGrpWithNFSCall
346     [Arguments]     ${url}
347     Create Session  pmsh_session      ${PMSH_BASE_URL}    verify=false
348     ${resp}=        GET On Session    pmsh_session        url=${url}
349     [Return]        ${resp}
350
351 PostSubscriptionCall
352     [Arguments]     ${url}     ${data}
353     Create Session  pmsh_sub_session       ${PMSH_BASE_URL}    verify=false
354     ${headers}=     Create Dictionary    Accept=application/json     Content-Type=application/json
355     ${resp}=        POST On Session      pmsh_sub_session    url=${url}    json=${data}     headers=${headers}  expected_status=anything
356     [Return]        ${resp}
357
358 PutMsgGrpStatusCall
359     [Arguments]     ${url}     ${data}
360     Create Session  pmsh_sub_session       ${PMSH_BASE_URL}    verify=false
361     ${headers}=     Create Dictionary    Accept=application/json     Content-Type=application/json
362     ${resp}=        PUT On Session      pmsh_sub_session    url=${url}    json=${data}     headers=${headers}  expected_status=anything
363     [Return]        ${resp}