Change comparestream usage
[integration/test.git] / csit / suites / bgpcep / bgpuser / basic.robot
1 *** Settings ***
2 Documentation     Basic tests for odl-bgpcep-bgp-all feature.
3 ...
4 ...               Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
5 ...
6 ...               This program and the accompanying materials are made available under the
7 ...               terms of the Eclipse Public License v1.0 which accompanies this distribution,
8 ...               and is available at http://www.eclipse.org/legal/epl-v10.html
9 ...
10 ...               Test suite performs basic BGP functional test cases:
11 ...               BGP peer initiated connection
12 ...               - introduce and check 3 prefixes in one update message
13 ...               ODL controller initiated connection:
14 ...               - introduce and check 3 prefixes in one update message
15 ...               - introduce 2 prefixes in first update message and then additional 2 prefixes
16 ...               in another update while the very first prefix is withdrawn
17 ...               - introduce 3 prefixes and try to withdraw the first one
18 ...               (to be ignored by controller) in a single update message
19 ...
20 ...               For versions Oxygen and further, there are TC_R (test case reset) which
21 ...               test session-reset functionality.
22 ...               Resets the session, and than verifies that example-ipv4-topology is empty again.
23 ...
24 ...               For versions Fluorine and further, there are TC_PG (test case peer group) which
25 ...               test configuration and reconfiguration of peer-groups and neighbors configured by them.
26 ...               - configure peer-group, and assign neighbor to this peer-group
27 ...               - check filled topology
28 ...               - reconfigure peer-group without ipv4 unicast afi-safi
29 ...               - check empty topology
30 ...               - reconfigre neighbor without peer-group, delete peer-group
31 ...
32 ...               Brief description how to perform BGP functional test:
33 ...               https://wiki.opendaylight.org/view/BGP_LS_PCEP:Lithium_Feature_Tests#How_to_test_2
34 ...
35 ...               Reported bugs:
36 ...               https://bugs.opendaylight.org/show_bug.cgi?id=4409
37 ...               https://bugs.opendaylight.org/show_bug.cgi?id=4634
38 Suite Setup       Setup_Everything
39 Suite Teardown    Teardown_Everything
40 Test Setup        SetupUtils.Setup_Test_With_Logging_And_Fast_Failing
41 Test Teardown     FailFast.Start_Failing_Fast_If_This_Failed
42 Library           OperatingSystem
43 Library           SSHLibrary    timeout=10s
44 Library           RequestsLibrary
45 Library           ../../../libraries/norm_json.py
46 Variables         ../../../variables/bgpuser/variables.py    ${TOOLS_SYSTEM_IP}    ${ODL_STREAM}
47 Resource          ../../../variables/Variables.robot
48 Resource          ../../../libraries/BGPcliKeywords.robot
49 Resource          ../../../libraries/BGPSpeaker.robot
50 Resource          ../../../libraries/FailFast.robot
51 Resource          ../../../libraries/KillPythonTool.robot
52 Resource          ../../../libraries/SetupUtils.robot
53 Resource          ../../../libraries/SSHKeywords.robot
54 Resource          ../../../libraries/TemplatedRequests.robot
55 Resource          ../../../libraries/Utils.robot
56 Resource          ../../../libraries/WaitForFailure.robot
57 Resource          ../../../libraries/CompareStream.robot
58
59 *** Variables ***
60 ${ACTUAL_RESPONSES_FOLDER}    ${TEMPDIR}/actual
61 ${EXPECTED_RESPONSES_FOLDER}    ${TEMPDIR}/expected
62 ${BGP_VARIABLES_FOLDER}    ${CURDIR}/../../../variables/bgpuser/
63 ${TOOLS_SYSTEM_PROMPT}    ${DEFAULT_LINUX_PROMPT}
64 ${HOLDTIME}       180
65 ${BGP_TOOL_LOG_LEVEL}    info
66 ${ODL_LOG_LEVEL}    INFO
67 ${ODL_BGP_LOG_LEVEL}    DEFAULT
68 ${CONFIG_SESSION}    session
69 ${PEER_GROUP}     internal-neighbors
70 ${PROTOCOL_OPENCONFIG}    ${RIB_INSTANCE}
71 ${DEVICE_NAME}    controller-config
72 ${BGP_PEER_NAME}    example-bgp-peer
73 ${RIB_INSTANCE}    example-bgp-rib
74
75 *** Test Cases ***
76 Check_For_Empty_Topology_Before_Talking
77     [Documentation]    Sanity check example-ipv4-topology is up but empty.
78     [Tags]    critical
79     Wait_For_Topology_To_Change_To    ${empty_json}    010_Empty.json    timeout=180s
80
81 Reconfigure_ODL_To_Accept_Connection
82     [Documentation]    Configure BGP peer module with initiate-connection set to false.
83     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}
84     ...    INITIATE=false    BGP_RIB=${RIB_INSTANCE}    PASSIVE_MODE=true    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}
85     TemplatedRequests.Put_As_Xml_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    mapping=${mapping}    session=${CONFIG_SESSION}
86     [Teardown]    SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
87
88 Start_Talking_BGP_speaker
89     [Documentation]    Start Python speaker to connect to ODL, verify that the tool does not promptly exit.
90     # Myport value is needed for checking whether connection at precise port was established.
91     BGPSpeaker.Start_BGP_Speaker    --amount 3 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_TOOL_LOG_LEVEL}
92     Read_And_Fail_If_Prompt_Is_Seen
93
94 Check_Talking_Connection_Is_Established
95     [Documentation]    See TCP (BGP) connection in established state.
96     # This case is separate from the previous one, to resemble structure of the second half of this suite more closely.
97     Check_Speaker_Is_Connected
98     [Teardown]    Utils.Report_Failure_Due_To_Bug    5171
99
100 Check_Talking_Topology_Is_Filled
101     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
102     [Tags]    critical
103     Wait_For_Topology_To_Change_To    ${filled_json}    020_Filled.json
104
105 TC_R_Reset_Bgp_Peer_Session
106     [Documentation]    Reset Peer Session
107     [Tags]    Critical
108     CompareStream.Run_Keyword_If_Less_Than_Oxygen    BuiltIn.Pass_Execution    Test case valid only for versions oxygen and above.
109     &{mapping}    Create Dictionary    IP=${TOOLS_SYSTEM_IP}    RIB_INSTANCE_NAME=${RIB_INSTANCE}
110     TemplatedRequests.Post_As_Xml_Templated    folder=${BGP_VARIABLES_FOLDER}${/}peer_session/restart    mapping=${mapping}    session=${CONFIG_SESSION}
111
112 TC_R_Check_For_Empty_Topology_After_Resetting
113     [Documentation]    See example-ipv4-topology empty after resetting session
114     [Tags]    critical
115     CompareStream.Run_Keyword_If_Less_Than_Oxygen    BuiltIn.Pass_Execution    Test case valid only for versions oxygen and above.
116     Wait_For_Topology_To_Change_To    ${empty_json}    030_Empty.json
117
118 TC_PG_Reconfigure_ODL_With_Peer_Group_To_Accept_Connection
119     [Documentation]    Configure BGP peer module with initiate-connection set to false.
120     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
121     &{mapping}    BuiltIn.Create_Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}
122     TemplatedRequests.Delete_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    mapping=${mapping}    session=${CONFIG_SESSION}
123     Configure_Peer_Group
124     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}
125     ...    PEER_GROUP_NAME=${PEER_GROUP}    INITIATE=false    BGP_RIB=${RIB_INSTANCE}    PASSIVE_MODE=true    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}
126     TemplatedRequests.Put_As_Xml_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer_group    mapping=${mapping}    session=${CONFIG_SESSION}
127     [Teardown]    SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
128
129 TC_PG_Restart_Talking_BGP_Speaker
130     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast.
131     [Tags]    critical
132     [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
133     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
134     Restart_Talking_BGP_Speaker
135     [Teardown]    FailFast.Do_Not_Start_Failing_If_This_Failed
136
137 TC_PG_Check_Talking_Topology_Is_Filled
138     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
139     [Tags]    critical
140     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
141     Wait_For_Topology_To_Change_To    ${filled_json}    021_Filled.json
142
143 TC_PG_Reconfigure_ODL_With_Peer_Group_Without_Ipv4_Unicast
144     [Documentation]    Configure BGP peer module with initiate-connection set to false. (Fluorine only)
145     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
146     Configure_Peer_Group    peer_group_folder=peer_group_without_ipv4
147     [Teardown]    SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
148
149 TC_PG_Check_For_Empty_Topology_After_Deconfiguration
150     [Documentation]    See example-ipv4-topology empty after resetting session (Fluorine only)
151     [Tags]    critical
152     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
153     Wait_For_Topology_To_Change_To    ${empty_json}    031_Empty.json
154
155 TC_PG_Reconfigure_ODL_To_Accept_Connection
156     [Documentation]    Configure BGP peer module with initiate-connection set to false. (Fluorine only)
157     CompareStream.Run_Keyword_If_Less_Than_Fluorine    BuiltIn.Pass_Execution    Test case valid only for versions fluorine and above.
158     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}
159     ...    PEER_GROUP_NAME=${PEER_GROUP}    INITIATE=false    BGP_RIB=${RIB_INSTANCE}    PASSIVE_MODE=true    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}
160     TemplatedRequests.Delete_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer_group    mapping=${mapping}    session=${CONFIG_SESSION}
161     TemplatedRequests.Put_As_Xml_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    mapping=${mapping}    session=${CONFIG_SESSION}
162     Deconfigure_Peer_Group
163     [Teardown]    SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
164
165 Kill_Talking_BGP_Speaker
166     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast.
167     [Tags]    critical
168     [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
169     BGPSpeaker.Kill_BGP_Speaker
170     FailFast.Do_Not_Fail_Fast_From_Now_On
171     # NOTE: It is still possible to remain failing fast, if both previous and this test have failed.
172     [Teardown]    FailFast.Do_Not_Start_Failing_If_This_Failed
173
174 Check_For_Empty_Topology_After_Talking
175     [Documentation]    See example-ipv4-topology empty again.
176     [Tags]    critical
177     Wait_For_Topology_To_Change_To    ${empty_json}    030_Empty.json
178
179 Start_Listening_BGP_Speaker
180     [Documentation]    Start Python speaker in listening mode, verify that the tool does not exit quickly.
181     BGPSpeaker.Start_BGP_Speaker    --amount 3 --listen --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --${BGP_TOOL_LOG_LEVEL}
182     Read_And_Fail_If_Prompt_Is_Seen
183
184 Check_Listening_Connection_Is_Not_Established_Yet
185     [Documentation]    See no TCP connection, as both ODL and tool are in listening mode.
186     Check_Speaker_Is_Not_Connected
187
188 Check_For_Empty_Topology_Before_Listening
189     [Documentation]    Sanity check example-ipv4-topology is still empty.
190     [Tags]    critical
191     Verify_That_Topology_Does_Not_Change_From    ${empty_json}    040_Empty.json
192
193 Reconfigure_ODL_To_Initiate_Connection
194     [Documentation]    Replace BGP peer config module, now with initiate-connection set to true.
195     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}
196     ...    INITIATE=true    BGP_RIB=${RIB_INSTANCE}    PASSIVE_MODE=false    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}
197     TemplatedRequests.Put_As_Xml_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    mapping=${mapping}    session=${CONFIG_SESSION}
198
199 Check_Listening_Connection_Is_Established
200     [Documentation]    See TCP (BGP) connection in established state.
201     Check_Speaker_Is_Connected
202
203 Check_Listening_Topology_Is_Filled
204     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
205     [Tags]    critical
206     Wait_For_Topology_To_Change_To    ${filled_json}    050_Filled.json
207
208 Kill_Listening_BGP_Speaker
209     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast.
210     [Tags]    critical
211     [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
212     BGPSpeaker.Kill_BGP_Speaker
213     FailFast.Do_Not_Fail_Fast_From_Now_On
214     # NOTE: It is still possible to remain failing fast, if both previous and this test have failed.
215     [Teardown]    FailFast.Do_Not_Start_Failing_If_This_Failed
216
217 Check_For_Empty_Topology_After_Listening
218     [Documentation]    Post-condition: Check example-ipv4-topology is empty again.
219     [Tags]    critical
220     Wait_For_Topology_To_Change_To    ${empty_json}    060_Empty.json
221
222 Start_Listening_BGP_Speaker_Case_2
223     [Documentation]    BGP Speaker introduces 2 prefixes in the first update & another 2 prefixes while the very first is withdrawn in 2nd update
224     BGPSpeaker.Start_BGP_Speaker    --amount 3 --listen --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --prefill=2 --insert=2 --withdraw=1 --updates=single --firstprefix=8.0.0.240 --${BGP_TOOL_LOG_LEVEL}
225     Read_And_Fail_If_Prompt_Is_Seen
226
227 Check_Listening_Connection_Is_Established_Case_2
228     [Documentation]    See TCP (BGP) connection in established state.
229     Check_Speaker_Is_Connected
230
231 Check_Listening_Topology_Is_Filled_Case_2
232     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
233     [Tags]    critical
234     Wait_For_Topology_To_Change_To    ${filled_json}    050_Filled.json
235     [Teardown]    Report_Failure_Due_To_Bug    4409
236
237 Kill_Listening_BGP_Speaker_Case_2
238     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast.
239     [Tags]    critical
240     [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
241     BGPSpeaker.Kill_BGP_Speaker
242     FailFast.Do_Not_Fail_Fast_From_Now_On
243     # NOTE: It is still possible to remain failing fast, if both previous and this test have failed.
244     [Teardown]    FailFast.Do_Not_Start_Failing_If_This_Failed
245
246 Check_For_Empty_Topology_After_Listening_Case_2
247     [Documentation]    Post-condition: Check example-ipv4-topology is empty again.
248     [Tags]    critical
249     Wait_For_Topology_To_Change_To    ${empty_json}    060_Empty.json
250
251 Start_Listening_BGP_Speaker_Case_3
252     [Documentation]    BGP Speaker introduces 3 prefixes while the first one occures again in the withdrawn list (to be ignored bu controller)
253     BGPSpeaker.Start_BGP_Speaker    --amount 2 --listen --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --prefill=0 --insert=3 --withdraw=1 --updates=single --${BGP_TOOL_LOG_LEVEL}
254     Read_And_Fail_If_Prompt_Is_Seen
255
256 Check_Listening_Connection_Is_Established_Case_3
257     [Documentation]    See TCP (BGP) connection in established state.
258     Check_Speaker_Is_Connected
259
260 Check_Listening_Topology_Is_Filled_Case_3
261     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
262     [Tags]    critical
263     Wait_For_Topology_To_Change_To    ${filled_json}    050_Filled.json
264     [Teardown]    Report_Failure_Due_To_Bug    4634
265
266 Kill_Listening_BGP_Speaker_Case_3
267     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast.
268     [Tags]    critical
269     [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
270     BGPSpeaker.Kill_BGP_Speaker
271     FailFast.Do_Not_Fail_Fast_From_Now_On
272     # NOTE: It is still possible to remain failing fast, if both previous and this test have failed.
273     [Teardown]    FailFast.Do_Not_Start_Failing_If_This_Failed
274
275 Check_For_Empty_Topology_After_Listening_Case_3
276     [Documentation]    Post-condition: Check example-ipv4-topology is empty again.
277     [Tags]    critical
278     Wait_For_Topology_To_Change_To    ${empty_json}    060_Empty.json
279
280 Delete_Bgp_Peer_Configuration
281     [Documentation]    Revert the BGP configuration to the original state: without any configured peers.
282     &{mapping}    BuiltIn.Create_Dictionary    DEVICE_NAME=${DEVICE_NAME}    BGP_NAME=${BGP_PEER_NAME}    IP=${TOOLS_SYSTEM_IP}    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}
283     TemplatedRequests.Delete_Templated    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    mapping=${mapping}    session=${CONFIG_SESSION}
284     # TODO: Do we need to check something else?
285
286 *** Keywords ***
287 Setup_Everything
288     [Documentation]    Initialize SetupUtils. SSH-login to mininet machine, create HTTP session,
289     ...    prepare directories for responses, put Python tool to mininet machine, setup imported resources.
290     SetupUtils.Setup_Utils_For_Setup_And_Teardown
291     SSHLibrary.Set_Default_Configuration    prompt=${TOOLS_SYSTEM_PROMPT}
292     RequestsLibrary.Create_Session    operational    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}${OPERATIONAL_TOPO_API}    auth=${AUTH}
293     # TODO: Do not include slash in ${OPERATIONAL_TOPO_API}, having it typed here is more readable.
294     # TODO: Alternatively, create variable in Variables which starts with http.
295     # Both TODOs would probably need to update every suite relying on current Variables.
296     OperatingSystem.Remove_Directory    ${EXPECTED_RESPONSES_FOLDER}    recursive=True
297     OperatingSystem.Remove_Directory    ${ACTUAL_RESPONSES_FOLDER}    recursive=True
298     # The previous suite may have been using the same directories.
299     OperatingSystem.Create_Directory    ${EXPECTED_RESPONSES_FOLDER}
300     OperatingSystem.Create_Directory    ${ACTUAL_RESPONSES_FOLDER}
301     SSHLibrary.Open_Connection    ${TOOLS_SYSTEM_IP}
302     SSHKeywords.Flexible_Mininet_Login
303     SSHKeywords.Require_Python
304     SSHKeywords.Assure_Library_Ipaddr    target_dir=.
305     SSHLibrary.Put_File    ${CURDIR}/../../../../tools/fastbgp/play.py
306     RequestsLibrary.Create_Session    ${CONFIG_SESSION}    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}    auth=${AUTH}
307     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_LOG_LEVEL}
308     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_BGP_LOG_LEVEL} org.opendaylight.bgpcep
309     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_BGP_LOG_LEVEL} org.opendaylight.protocol
310
311 Teardown_Everything
312     [Documentation]    Create and Log the diff between expected and actual responses, make sure Python tool was killed.
313     ...    Tear down imported Resources.
314     ${diff}=    OperatingSystem.Run    diff -dur ${EXPECTED_RESPONSES_FOLDER} ${ACTUAL_RESPONSES_FOLDER}
315     BuiltIn.Log    ${diff}
316     KillPythonTool.Search_And_Kill_Remote_Python    'play\.py'
317     RequestsLibrary.Delete_All_Sessions
318     SSHLibrary.Close_All_Connections
319
320 Wait_For_Topology_To_Change_To
321     [Arguments]    ${json_topology}    ${filename}    ${timeout}=10s    ${refresh}=1s
322     [Documentation]    Normalize the expected json topology and save it to ${EXPECTED_RESPONSES_FOLDER}.
323     ...    Wait until Compare_Topology matches. ${ACTUAL_RESPONSES_FOLDER} will hold its last result.
324     ${topology_normalized}=    Normalize_And_Save_Expected_Json    ${json_topology}    ${filename}    ${EXPECTED_RESPONSES_FOLDER}
325     BuiltIn.Wait_Until_Keyword_Succeeds    ${timeout}    ${refresh}    Compare_Topology    ${topology_normalized}    ${filename}
326
327 Verify_That_Topology_Does_Not_Change_From
328     [Arguments]    ${json_topology}    ${filename}    ${timeout}=10s    ${refresh}=1s
329     [Documentation]    Normalize the expected json topology and save it to ${EXPECTED_RESPONSES_FOLDER}.
330     ...    Verify that Compare_Topology keeps passing. ${ACTUAL_RESPONSES_FOLDER} will hold its last result.
331     ${topology_normalized}=    Normalize_And_Save_Expected_Json    ${json_topology}    ${filename}    ${EXPECTED_RESPONSES_FOLDER}
332     WaitForFailure.Verify_Keyword_Does_Not_Fail_Within_Timeout    ${timeout}    ${refresh}    Compare_Topology    ${topology_normalized}    ${filename}
333
334 Compare_Topology
335     [Arguments]    ${expected_normalized}    ${filename}
336     [Documentation]    Get current example-ipv4-topology as json, normalize it, save to ${ACTUAL_RESPONSES_FOLDER}.
337     ...    Check that status code is 200, check that normalized jsons match exactly.
338     ${response}=    RequestsLibrary.Get Request    operational    topology/example-ipv4-topology
339     BuiltIn.Log    ${response.status_code}
340     BuiltIn.Log    ${response.text}
341     ${actual_normalized}=    Normalize_And_Save_Expected_Json    ${response.text}    ${filename}    ${ACTUAL_RESPONSES_FOLDER}
342     BuiltIn.Should_Be_Equal_As_Strings    ${response.status_code}    200
343     BuiltIn.Should_Be_Equal    ${actual_normalized}    ${expected_normalized}
344
345 Normalize_And_Save_Expected_Json
346     [Arguments]    ${json_text}    ${filename}    ${directory}
347     [Documentation]    Normalize given json using norm_json library. Log and save the result to given filename under given directory.
348     ${json_normalized}=    norm_json.normalize_json_text    ${json_text}
349     BuiltIn.Log    ${json_normalized}
350     OperatingSystem.Create_File    ${directory}${/}${filename}    ${json_normalized}
351     # TODO: Should we prepend .json to the filename? When we detect it is not already prepended?
352     [Return]    ${json_normalized}
353
354 Check_Speaker_Is_Not_Connected
355     [Documentation]    Give it a few tries to see zero established connections.
356     BuiltIn.Wait_Until_Keyword_Succeeds    3s    1s    Check_Number_Of_Speaker_Connections    0
357
358 Check_Speaker_Is_Connected
359     [Documentation]    Give it several tries to see exactly one established connection.
360     BuiltIn.Wait_Until_Keyword_Succeeds    5s    1s    Check_Number_Of_Speaker_Connections    1
361
362 Check_Number_Of_Speaker_Connections
363     [Arguments]    ${howmany}
364     [Documentation]    Run netstat in mininet machine and parse it for number of established connections. Check it is ${howmany}.
365     ${output}=    SSHKeywords.Count_Port_Occurences    17900    ESTABLISHED    python
366     BuiltIn.Should_Be_Equal_As_Strings    ${output}    ${howmany}
367
368 Configure_Peer_Group
369     [Arguments]    ${peer_group_folder}=peer_group
370     [Documentation]    Configures peer group which is template for all the neighbors which are going
371     ...    to be configured. Also after PUT, this case verifies presence of peer group within
372     ...    peer-groups. This case is specific to versions Fluorine and above.
373     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}    INITIATE=false    BGP_RIB=${RIB_INSTANCE}
374     ...    PASSIVE_MODE=true    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}    PEER_GROUP_NAME=${PEER_GROUP}    RR_CLIENT=false
375     TemplatedRequests.Put_As_Xml_Templated    ${BGP_VARIABLES_FOLDER}${/}${peer_group_folder}    mapping=${mapping}    session=${CONFIG_SESSION}
376     TemplatedRequests.Get_As_Json_Templated    ${BGP_VARIABLES_FOLDER}${/}verify_${peer_group_folder}    mapping=${mapping}    session=${CONFIG_SESSION}    verify=True
377
378 Deconfigure_Peer_Group
379     [Documentation]    Deconfigures peer group which is template for all the neighbors
380     ...    This test case is specific to versions Fluorine and above.
381     &{mapping}    Create Dictionary    DEVICE_NAME=${DEVICE_NAME}    HOLDTIME=${HOLDTIME}    PEER_PORT=${BGP_TOOL_PORT}    INITIATE=false    BGP_RIB=${RIB_INSTANCE}
382     ...    PASSIVE_MODE=true    BGP_RIB_OPENCONFIG=${PROTOCOL_OPENCONFIG}    RIB_INSTANCE_NAME=${RIB_INSTANCE}    PEER_GROUP_NAME=${PEER_GROUP}    RR_CLIENT=false
383     TemplatedRequests.Delete_Templated    ${BGP_VARIABLES_FOLDER}${/}peer_group    mapping=${mapping}    session=${CONFIG_SESSION}
384
385 Restart_Talking_BGP_Speaker
386     [Documentation]    Abort the Python speaker. Also, attempt to stop failing fast. And Start it again.
387     ...    We have to restart it this way because we reset session before
388     BGPSpeaker.Kill_BGP_Speaker
389     FailFast.Do_Not_Fail_Fast_From_Now_On
390     BGPSpeaker.Start_BGP_Speaker    --amount 3 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_TOOL_LOG_LEVEL}
391     Read_And_Fail_If_Prompt_Is_Seen