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