80bee784d0a1447bf6ec24916b60fa11d0a9960b
[integration/test.git] / csit / suites / bgpcep / bgpuser / bgp_app_peer_basic.robot
1 *** Settings ***
2 Documentation     Basic tests for BGP application peer.
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 for
11 ...               BGP application peer.
12 ...
13 ...               Brief description how to configure BGP application peer and
14 ...               how to use restconf application peer interface:
15 ...               https://wiki.opendaylight.org/view/BGP_LS_PCEP:User_Guide#BGP_Application_Peer
16 ...               https://wiki.opendaylight.org/view/BGP_LS_PCEP:Programmer_Guide#BGP
17 ...               Covered bugs:
18 ...               Bug 4714 - No routes from loc-rib are advertised to newly connected peer
19 Suite Setup       Setup_Everything
20 Suite Teardown    Teardown_Everything
21 Test Setup        SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
22 Test Teardown     FailFast.Start_Failing_Fast_If_This_Failed
23 Library           OperatingSystem
24 Library           SSHLibrary    timeout=10s
25 Library           RequestsLibrary
26 Library           ${CURDIR}/../../../libraries/HsfJson/hsf_json.py
27 Variables         ${CURDIR}/../../../variables/Variables.py
28 Variables         ${CURDIR}/../../../variables/bgpuser/variables.py    ${TOOLS_SYSTEM_IP}
29 Resource          ${CURDIR}/../../../libraries/BGPSpeaker.robot
30 Resource          ${CURDIR}/../../../libraries/ConfigViaRestconf.robot
31 Resource          ${CURDIR}/../../../libraries/FailFast.robot
32 Resource          ${CURDIR}/../../../libraries/KarafKeywords.robot
33 Resource          ${CURDIR}/../../../libraries/KillPythonTool.robot
34 Resource          ${CURDIR}/../../../libraries/SetupUtils.robot
35 Resource          ${CURDIR}/../../../libraries/SSHKeywords.robot
36 Resource          ${CURDIR}/../../../libraries/Utils.robot
37 Resource          ${CURDIR}/../../../libraries/WaitForFailure.robot
38
39 *** Variables ***
40 ${ACTUAL_RESPONSES_FOLDER}    ${TEMPDIR}/actual
41 ${EXPECTED_RESPONSES_FOLDER}    ${TEMPDIR}/expected
42 ${BGP_VARIABLES_FOLDER}    ${CURDIR}/../../../variables/bgpuser/
43 ${TOOLS_SYSTEM_PROMPT}    ${DEFAULT_LINUX_PROMPT}
44 ${HOLDTIME}       180
45 ${BGP_PEER_LOG_LEVEL}    debug
46 ${BGP_APP_PEER_LOG_LEVEL}    debug
47 ${CONTROLLER_LOG_LEVEL}    INFO
48 ${CONTROLLER_BGP_LOG_LEVEL}    DEFAULT
49 ${BGP_PEER_COMMAND}    python play.py --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL}
50 ${BGP_PEER_OPTIONS}    ${EMPTY}
51 ${BGP_APP_PEER_ID}    10.0.0.10
52 ${BGP_APP_PEER_POST_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command post --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL}
53 ${BGP_APP_PEER_PUT_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command put --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL}
54 ${BGP_APP_PEER_DELETE_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL}
55 ${BGP_APP_PEER_DELETE_ALL_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete-all --${BGP_APP_PEER_LOG_LEVEL}
56 ${BGP_APP_PEER_GET_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command get --${BGP_APP_PEER_LOG_LEVEL}
57 ${BGP_APP_PEER_OPTIONS}    &>/dev/null
58 ${BGP_APP_PEER_TIMEOUT}    30s
59
60 *** Test Cases ***
61 Reconfigure_ODL_To_Accept_BGP_Peer_Connection
62     [Documentation]    Configure BGP peer module with initiate-connection set to false.
63     [Tags]    critical
64     ${template_as_string}=    BuiltIn.Set_Variable    {'NAME': 'example-bgp-peer', 'IP': '${TOOLS_SYSTEM_IP}', 'HOLDTIME': '${HOLDTIME}', 'PEER_PORT': '${BGP_TOOL_PORT}', 'INITIATE': 'false'}
65     ConfigViaRestconf.Put_Xml_Template_Folder_Config_Via_Restconf    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    ${template_as_string}
66
67 Reconfigure_ODL_To_Accept_BGP_Application_Peer
68     [Documentation]    Configure BGP application peer module.
69     [Tags]    critical
70     ${template_as_string}=    BuiltIn.Set_Variable    {'NAME': 'example-bgp-peer-app', 'IP': '${BGP_APP_PEER_ID}'}
71     ConfigViaRestconf.Put_Xml_Template_Folder_Config_Via_Restconf    ${BGP_VARIABLES_FOLDER}${/}bgp_application_peer    ${template_as_string}
72
73 Check_For_Empty_Example-IPv4-Topology
74     [Documentation]    Sanity check example-ipv4-topology is up but empty.
75     [Tags]    critical
76     Wait_For_Topology_To_Change_To    ${empty_json}    000_Empty.json    timeout=120s
77
78 TC1_BGP_Application_Peer_Post_3_Initial_Routes
79     [Documentation]    Start BGP application peer tool and give it ${BGP_APP_PEER_TIMEOUT}
80     [Tags]    critical
81     Switch_To_BGP_Application_Peer_Console
82     Start_Console_Tool    ${BGP_APP_PEER_POST_COMMAND}    ${BGP_APP_PEER_OPTIONS}
83     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
84     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_initial_post_tc1.log
85
86 TC1_Check_Example-IPv4-Topology_Is_Filled_With_3_Routes
87     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
88     [Tags]    critical
89     Wait_For_Topology_To_Change_To    ${filled_json}    010_Filled.json
90
91 TC1_Connect_BGP_Peer
92     [Documentation]    Start BGP peer tool
93     [Tags]    critical
94     Switch_To_BGP_Peer_Console
95     Start_Console_Tool    ${BGP_PEER_COMMAND}    ${BGP_PEER_OPTIONS}
96     Read_And_Fail_If_Prompt_Is_Seen
97
98 TC1_BGP_Peer_Check_Incomming_Updates_For_3_Introduced_Prefixes
99     [Documentation]    Check incomming updates for new routes
100     [Tags]    critical
101     Switch_To_BGP_Peer_Console
102     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
103     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.0/28    1
104     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.16/28    1
105     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.32/28    1
106     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    0
107     [Teardown]    Report_Failure_Due_To_Bug    4714
108
109 TC1_BGP_Application_Peer_Delete_3_Initial_Routes
110     [Documentation]    Start BGP application peer tool and give him ${BGP_APP_PEER_TIMEOUT}
111     [Tags]    critical
112     Switch_To_BGP_Application_Peer_Console
113     Start_Console_Tool    ${BGP_APP_PEER_DELETE_COMMAND}    ${BGP_APP_PEER_OPTIONS}
114     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
115     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_delete_tc1.log
116
117 TC1_Check_Example-IPv4-Topology_Is_Empty
118     [Documentation]    See new routes are deleted.
119     [Tags]    critical
120     Wait_For_Topology_To_Change_To    ${empty_json}    011_Empty.json
121
122 TC1_Peer_Check_Incomming_Updates_For_3_Withdrawn_Prefixes
123     [Documentation]    Check incomming updates for new routes
124     [Tags]    critical
125     Switch_To_BGP_Peer_Console
126     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    3
127     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.0/28    1
128     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.16/28    1
129     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.32/28    1
130     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
131     [Teardown]    Report_Failure_Due_To_Bug    4714
132
133 TC1_Stop_BGP_Peer
134     [Documentation]    Stop BGP peer tool
135     [Tags]    critical
136     Switch_To_BGP_Peer_Console
137     Stop_Console_Tool
138     Store_File_To_Workspace    bgp_peer.log    bgp_peer_tc1.log
139
140 TC2_Connect_BGP_Peer
141     [Documentation]    Start BGP peer tool
142     [Tags]    critical
143     Switch_To_BGP_Peer_Console
144     Start_Console_Tool    ${BGP_PEER_COMMAND}    ${BGP_PEER_OPTIONS}
145     Read_And_Fail_If_Prompt_Is_Seen
146     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    0
147     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    0
148
149 TC2_BGP_Application_Peer_Put_3_Routes
150     [Documentation]    Start BGP application peer tool and give him ${BGP_APP_PEER_TIMEOUT}
151     [Tags]    critical
152     Switch_To_BGP_Application_Peer_Console
153     Start_Console_Tool    ${BGP_APP_PEER_PUT_COMMAND}    ${BGP_APP_PEER_OPTIONS}
154     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
155     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_put_tc2.log
156
157 TC2_Check_Example-IPv4-Topology_Is_Filled_With_3_Routes
158     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
159     [Tags]    critical
160     Wait_For_Topology_To_Change_To    ${filled_json}    020_Filled.json
161
162 TC2_BGP_Peer_Check_Incomming_Updates_For_3_Introduced_Prefixes
163     [Documentation]    Check incomming updates for new routes
164     [Tags]    critical
165     Switch_To_BGP_Peer_Console
166     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
167     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.0/28    1
168     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.16/28    1
169     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.32/28    1
170     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    0
171
172 TC2_BGP_Application_Peer_Delete_All_Routes
173     [Documentation]    Start BGP application peer tool and give him ${BGP_APP_PEER_TIMEOUT}
174     [Tags]    critical
175     Switch_To_BGP_Application_Peer_Console
176     Start_Console_Tool    ${BGP_APP_PEER_DELETE_ALL_COMMAND}    ${BGP_APP_PEER_OPTIONS}
177     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
178     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_delete_all_tc2.log
179
180 TC2_Check_Example-IPv4-Topology_Is_Empty
181     [Documentation]    See new routes are deleted.
182     [Tags]    critical
183     Wait_For_Topology_To_Change_To    ${empty_json}    021_Empty.json
184
185 TC2_BGP_Peer_Check_Incomming_Updates_For_3_Withdrawn_Prefixes
186     [Documentation]    Check incomming updates for new routes
187     [Tags]    critical
188     Switch_To_BGP_Peer_Console
189     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    3
190     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.0/28    1
191     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.16/28    1
192     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.32/28    1
193     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
194
195 TC2_Stop_BGP_Peer
196     [Documentation]    Stop BGP peer tool
197     [Tags]    critical
198     Switch_To_BGP_Peer_Console
199     Stop_Console_Tool
200     Store_File_To_Workspace    bgp_peer.log    bgp_peer_tc2.log
201
202 TC3_BGP_Application_Peer_Put_3_Routes
203     [Documentation]    Start BGP application peer tool and give him ${BGP_APP_PEER_TIMEOUT}
204     [Tags]    critical
205     Switch_To_BGP_Application_Peer_Console
206     Start_Console_Tool    ${BGP_APP_PEER_PUT_COMMAND}    ${BGP_APP_PEER_OPTIONS}
207     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
208     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_put_tc3.log
209
210 TC3_Check_Example-IPv4-Topology_Is_Filled_With_3_Routes
211     [Documentation]    See new routes in example-ipv4-topology as a proof that synchronization was correct.
212     [Tags]    critical
213     Wait_For_Topology_To_Change_To    ${filled_json}    030_Filled.json
214
215 TC3_Reconnect_BGP_Peer_And_Check_Incomming_Updates_For_3_Introduced_Prefixes
216     [Documentation]    Start BGP peer tool
217     [Tags]    critical
218     Switch_To_BGP_Peer_Console
219     Start_Console_Tool    ${BGP_PEER_COMMAND}    ${BGP_PEER_OPTIONS}
220     Read_And_Fail_If_Prompt_Is_Seen
221     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
222     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
223     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.0/28    1
224     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.16/28    1
225     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received: 8.0.1.32/28    1
226     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    0
227
228 TC3_BGP_Application_Peer_Delete_All_Routes
229     [Documentation]    Start BGP application peer tool and give him ${BGP_APP_PEER_TIMEOUT}
230     [Tags]    critical
231     Switch_To_BGP_Application_Peer_Console
232     Start_Console_Tool    ${BGP_APP_PEER_DELETE_ALL_COMMAND}    ${BGP_APP_PEER_OPTIONS}
233     Wait_Until_Console_Tool_Finish    ${BGP_APP_PEER_TIMEOUT}
234     Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_delete_all_tc3.log
235
236 TC3_Check_Example-IPv4-Topology_Is_Empty
237     [Documentation]    See new routes are deleted.
238     [Tags]    critical
239     Wait_For_Topology_To_Change_To    ${empty_json}    031_Empty.json
240
241 TC3_BGP_Peer_Check_Incomming_Updates_For_3_Withdrawn_Prefixes
242     [Documentation]    Check incomming updates for new routes
243     [Tags]    critical
244     Switch_To_BGP_Peer_Console
245     BuiltIn.Wait_Until_Keyword_Succeeds    60s    1s    Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received:    3
246     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.0/28    1
247     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.16/28    1
248     Check_File_For_Word_Count    bgp_peer.log    withdrawn_prefix_received: 8.0.1.32/28    1
249     Check_File_For_Word_Count    bgp_peer.log    nlri_prefix_received:    3
250
251 TC3_Stop_BGP_Peer
252     [Documentation]    Stop BGP peer tool
253     [Tags]    critical
254     Switch_To_BGP_Peer_Console
255     Stop_Console_Tool
256     Store_File_To_Workspace    bgp_peer.log    bgp_peer_tc3.log
257
258 Delete_Bgp_Peer_Configuration
259     [Documentation]    Revert the BGP configuration to the original state: without any configured peers.
260     [Tags]    critical
261     ${template_as_string}=    BuiltIn.Set_Variable    {'NAME': 'example-bgp-peer'}
262     ConfigViaRestconf.Delete_Xml_Template_Folder_Config_Via_Restconf    ${BGP_VARIABLES_FOLDER}${/}bgp_peer    ${template_as_string}
263
264 Delete_Bgp_Application_Peer_Configuration
265     [Documentation]    Revert the BGP configuration to the original state: without any configured peers.
266     [Tags]    critical
267     ${template_as_string}=    BuiltIn.Set_Variable    {'NAME': 'example-bgp-peer-app'}
268     ConfigViaRestconf.Delete_Xml_Template_Folder_Config_Via_Restconf    ${BGP_VARIABLES_FOLDER}${/}bgp_application_peer    ${template_as_string}
269
270 *** Keywords ***
271 Setup_Everything
272     [Documentation]    SSH-login to mininet machine, create HTTP session,
273     ...    prepare directories for responses, put Python tool to mininet machine, setup imported resources.
274     SetupUtils.Setup_Utils_For_Setup_And_Teardown
275     SSHLibrary.Set_Default_Configuration    prompt=${TOOLS_SYSTEM_PROMPT}
276     Open_BGP_Peer_Console
277     SSHLibrary.Put_File    ${CURDIR}/../../../../tools/fastbgp/play.py
278     Open_BGP_Aplicationp_Peer_Console
279     SSHLibrary.Put_File    ${CURDIR}/../../../../tools/fastbgp/bgp_app_peer.py
280     SSHLibrary.Put_File    ${CURDIR}/../../../../tools/fastbgp/ipv4-routes-template.xml
281     OperatingSystem.Remove_Directory    ${EXPECTED_RESPONSES_FOLDER}    recursive=True
282     OperatingSystem.Remove_Directory    ${ACTUAL_RESPONSES_FOLDER}    recursive=True
283     # The previous suite may have been using the same directories.
284     OperatingSystem.Create_Directory    ${EXPECTED_RESPONSES_FOLDER}
285     OperatingSystem.Create_Directory    ${ACTUAL_RESPONSES_FOLDER}
286     RequestsLibrary.Create_Session    operational    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}${OPERATIONAL_TOPO_API}    auth=${AUTH}
287     ConfigViaRestconf.Setup_Config_Via_Restconf
288     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${CONTROLLER_LOG_LEVEL}
289     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${CONTROLLER_BGP_LOG_LEVEL} org.opendaylight.bgpcep
290     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${CONTROLLER_BGP_LOG_LEVEL} org.opendaylight.protocol
291
292 Teardown_Everything
293     [Documentation]    Create and Log the diff between expected and actual responses, make sure Python tool was killed.
294     ...    Tear down imported Resources.
295     ${diff}=    OperatingSystem.Run    diff -dur ${EXPECTED_RESPONSES_FOLDER} ${ACTUAL_RESPONSES_FOLDER}
296     BuiltIn.Log    ${diff}
297     KillPythonTool.Search_And_Kill_Remote_Python    'play\.py'
298     KillPythonTool.Search_And_Kill_Remote_Python    'bgp_app_peer\.py'
299     ConfigViaRestconf.Teardown_Config_Via_Restconf
300     RequestsLibrary.Delete_All_Sessions
301     SSHLibrary.Close_All_Connections
302
303 Open_BGP_Peer_Console
304     [Documentation]    Create a session for BGP peer.
305     SSHLibrary.Open_Connection    ${TOOLS_SYSTEM_IP}    alias=bgp_peer_console
306     Utils.Flexible_Mininet_Login
307
308 Open_BGP_Aplicationp_Peer_Console
309     [Documentation]    Create a session for BGP peer.
310     SSHLibrary.Open_Connection    ${TOOLS_SYSTEM_IP}    alias=bgp_app_peer_console
311     Utils.Flexible_Mininet_Login
312
313 Switch_To_BGP_Peer_Console
314     SSHLibrary.Switch Connection    bgp_peer_console
315
316 Switch_To_BGP_Application_Peer_Console
317     SSHLibrary.Switch Connection    bgp_app_peer_console
318
319 Start_Console_Tool
320     [Arguments]    ${command}    ${tool_opt}
321     [Documentation]    Start the tool ${command} ${tool_opt}
322     BuiltIn.Log    ${command}
323     ${output}=    SSHLibrary.Write    ${command} ${tool_opt}
324     BuiltIn.Log    ${output}
325
326 Wait_Until_Console_Tool_Finish
327     [Arguments]    ${timeout}
328     [Documentation]    Wait ${timeout} for the tool exit.
329     BuiltIn.Wait Until Keyword Succeeds    ${timeout}    1s    SSHLibrary.Read Until Prompt
330
331 Stop_Console_Tool
332     [Documentation]    Stop the tool if still running.
333     Utils.Write_Bare_Ctrl_C
334     ${output}=    SSHLibrary.Read    delay=1s
335     BuiltIn.Log    ${output}
336
337 Wait_For_Topology_To_Change_To
338     [Arguments]    ${json_topology}    ${filename}    ${timeout}=10s    ${refresh}=1s
339     [Documentation]    Normalize the expected json topology and save it to ${EXPECTED_RESPONSES_FOLDER}.
340     ...    Wait until Compare_Topology matches. ${ACTUAL_RESPONSES_FOLDER} will hold its last result.
341     ${topology_normalized}=    Normalize_And_Save_Expected_Json    ${json_topology}    ${filename}    ${EXPECTED_RESPONSES_FOLDER}
342     BuiltIn.Wait_Until_Keyword_Succeeds    ${timeout}    ${refresh}    Compare_Topology    ${topology_normalized}    ${filename}
343
344 Verify_That_Topology_Does_Not_Change_From
345     [Arguments]    ${json_topology}    ${filename}    ${timeout}=10s    ${refresh}=1s
346     [Documentation]    Normalize the expected json topology and save it to ${EXPECTED_RESPONSES_FOLDER}.
347     ...    Verify that Compare_Topology keeps passing. ${ACTUAL_RESPONSES_FOLDER} will hold its last result.
348     ${topology_normalized}=    Normalize_And_Save_Expected_Json    ${json_topology}    ${filename}    ${EXPECTED_RESPONSES_FOLDER}
349     WaitForFailure.Verify_Keyword_Does_Not_Fail_Within_Timeout    ${timeout}    ${refresh}    Compare_Topology    ${topology_normalized}    ${filename}
350
351 Compare_Topology
352     [Arguments]    ${expected_normalized}    ${filename}
353     [Documentation]    Get current example-ipv4-topology as json, normalize it, save to ${ACTUAL_RESPONSES_FOLDER}.
354     ...    Check that status code is 200, check that normalized jsons match exactly.
355     ${response}=    RequestsLibrary.Get Request    operational    topology/example-ipv4-topology
356     BuiltIn.Log    ${response.status_code}
357     BuiltIn.Log    ${response.text}
358     ${actual_normalized}=    Normalize_And_Save_Expected_Json    ${response.text}    ${filename}    ${ACTUAL_RESPONSES_FOLDER}
359     BuiltIn.Should_Be_Equal_As_Strings    ${response.status_code}    200
360     BuiltIn.Should_Be_Equal    ${actual_normalized}    ${expected_normalized}
361
362 Normalize_And_Save_Expected_Json
363     [Arguments]    ${json_text}    ${filename}    ${directory}
364     [Documentation]    Normalize given json using hsf_json library. Log and save the result to given filename under given directory.
365     ${json_normalized}=    hsf_json.Hsf_Json    ${json_text}
366     BuiltIn.Log    ${json_normalized}
367     OperatingSystem.Create_File    ${directory}${/}${filename}    ${json_normalized}
368     # TODO: Should we prepend .json to the filename? When we detect it is not already prepended?
369     [Return]    ${json_normalized}
370
371 Read_And_Fail_If_Prompt_Is_Seen
372     [Documentation]    Try to read SSH to see prompt, but expect to see no prompt within SSHLibrary's timeout.
373     ${passed}=    BuiltIn.Run_Keyword_And_Return_Status    BuiltIn.Run_Keyword_And_Expect_Error    No match found for '${TOOLS_SYSTEM_PROMPT}' in *.    Read_Text_Before_Prompt
374     BuiltIn.Return_From_Keyword_If    ${passed}
375     BGPSpeaker.Dump_BGP_Speaker_Logs
376     Builtin.Fail    The prompt was seen but it was not expected yet
377
378 Read_Text_Before_Prompt
379     [Documentation]    Log text gathered by SSHLibrary.Read_Until_Prompt.
380     ...    This needs to be a separate keyword just because how Read_And_Fail_If_Prompt_Is_Seen is implemented.
381     ${text}=    SSHLibrary.Read_Until_Prompt
382     BuiltIn.Log    ${text}
383
384 Store_File_To_Workspace
385     [Arguments]    ${source_file_name}    ${target_file_name}
386     [Documentation]    Store the ${source_file_name} to the workspace as ${target_file_name}.
387     ${output_log}=    SSHLibrary.Execute_Command    cat ${source_file_name}
388     BuiltIn.Log    ${output_log}
389     Create File    ${target_file_name}    ${output_log}
390
391 Check_File_For_Word_Count
392     [Arguments]    ${file_name}    ${word}    ${expected_count}
393     [Documentation]    Count ${word} in ${file_name}. Expect ${expected_count} occurence(s)
394     ${output_log}=    SSHLibrary.Execute_Command    grep -o '${word}' ${file_name} | wc -l
395     BuiltIn.Log    ${output_log}
396     BuiltIn.Should_Be_Equal_As_Strings    ${output_log}    ${expected_count}