blob: 442ad3823db5c24fd3359276504ed928f3be1e5d [file]
*** Settings ***
Library String
Library Process
Library Collections
Library OperatingSystem
Library helper.py
*** Variables ***
${SERVER_REMOTE_DEBUG} False
${SERVER_REMOTE_PORT} 12345
${SERVER_REMOTE_SUSPEND} y
${SKIP_RUNNING_SERVER} False
${CONFIGURATION} Release
${PORT_NUMBER} 9999
${DIRECTORY} ${CURDIR}/../output/bin/${CONFIGURATION}
${RENODETOOLS} ${CURDIR}/../tools
${BINARY_NAME} Renode.dll
${HOTSPOT_ACTION} None
${DISABLE_GUI} False
${DEFAULT_UART_TIMEOUT} 8
${CREATE_SNAPSHOT_ON_FAIL} True
${SAVE_LOGS} True
${SAVE_LOGS_WHEN} Fail
${HOLD_ON_ERROR} False
${CREATE_EXECUTION_METRICS} False
${PROFILER_PROCESS} None
*** Keywords ***
Setup
${SYSTEM}= Evaluate platform.system() modules=platform
${CONFIGURATION}= Set Variable If not ${SKIP_RUNNING_SERVER} and ${SERVER_REMOTE_DEBUG}
... Debug
... ${CONFIGURATION}
# without --hide-log the output buffers may get full and the program can hang
# http://robotframework.org/robotframework/latest/libraries/Process.html#Standard%20output%20and%20error%20streams
@{PARAMS}= Create List --robot-server-port ${PORT_NUMBER} --hide-log
IF ${DISABLE_GUI}
Insert Into List ${PARAMS} 0 --disable-gui
END
IF not ${SKIP_RUNNING_SERVER}
File Should Exist ${DIRECTORY}/${BINARY_NAME} msg=Robot Framework remote server binary not found (${DIRECTORY}/${BINARY_NAME}). Did you forget to build it in ${CONFIGURATION} configuration?
END
IF not ${SKIP_RUNNING_SERVER} and ${SERVER_REMOTE_DEBUG} and '${SYSTEM}' == 'Windows'
Fatal Error Windows doesn't support server remote debug option.
END
#The distinction between operating systems is because localhost is not universally understood on Linux and 127.0.0.1 is not always available on Windows.
IF not '${SYSTEM}' == 'Windows'
Wait Until Keyword Succeeds 60s 1s
... Import Library Remote http://127.0.0.1:${PORT_NUMBER}/ AS Renode
END
IF '${SYSTEM}' == 'Windows'
Wait Until Keyword Succeeds 60s 1s
... Import Library Remote http://localhost:${PORT_NUMBER}/ AS Renode
END
Setup Renode
Setup Renode
Set Default Uart Timeout ${DEFAULT_UART_TIMEOUT}
${allowed_chars}= Set Variable abcdefghijklmnopqrstuvwxyz01234567890_-
${metrics_fname}= Convert To Lower Case ${SUITE_NAME}
${metrics_fname}= Replace String ${metrics_fname} ${SPACE} _
${metrics_fname}= Replace String Using Regexp ${metrics_fname} [^${allowed_chars}]+ ${EMPTY}
${metrics_path}= Join Path ${RESULTS_DIRECTORY} profiler-${metrics_fname}
IF ${CREATE_EXECUTION_METRICS}
Execute Command EnableProfilerGlobally "${metrics_path}"
END
Reset Emulation
Teardown
IF not ${SKIP_RUNNING_SERVER}
Stop Remote Server
END
IF not ${SKIP_RUNNING_SERVER}
Wait For Process
END
Sanitize Test Name
[Arguments] ${test_name}
${test_name}= Replace String ${test_name} ${SPACE} _
# double quotes because editor syntax highlighting gets confused with a single one
${test_name}= Replace String Using Regexp ${test_name} [/""] -
RETURN ${test_name}
Get Sanitized Test Name
${retry_index}= Get Variable Value \${RETRYFAILED_RETRY_INDEX} 0
${test_name}= Set Variable ${SUITE NAME}.${TEST NAME}.fail${retry_index}
${test_name}= Sanitize Test Name ${test_name}
RETURN ${test_name}
Create Snapshot Of Failed Test
Return From Keyword If 'skipped' in @{TEST TAGS}
${test_name}= Get Sanitized Test Name
${snapshots_dir}= Set Variable ${RESULTS_DIRECTORY}/snapshots
Create Directory ${snapshots_dir}
${snapshot_path}= Set Variable "${snapshots_dir}/${test_name}.save"
Execute Command Save ${snapshot_path}
Log To Console !!!!! Emulation's state saved to ${snapshot_path}
Get Test Log Path
${test_name}= Get Sanitized Test Name
${logs_dir}= Set Variable ${RESULTS_DIRECTORY}/logs
Create Directory ${logs_dir}
RETURN ${logs_dir}/${test_name}.log
Test Setup
IF 'profiling' in @{TEST TAGS}
Start Profiler
END
IF ${SAVE_LOGS}
${log_path}= Get Test Log Path
Open Log File ${log_path}
END
Reset Emulation
Print Log Saved Message
Return From Keyword If 'skipped' in @{TEST TAGS}
Return From Keyword If not ${SAVE_LOGS}
${log_path}= Get Test Log Path
Log To Console !!!!! Log saved to "${log_path}"
Remove Log
Return From Keyword If 'skipped' in @{TEST TAGS}
Return From Keyword If not ${SAVE_LOGS}
${log_path}= Get Test Log Path
Remove File ${log_path}
Test Teardown
Stop Profiler
${failed}= Run Keyword If Test Failed Set Variable True
IF ${failed}
# Some of the exception messages end with whitespace.
${message}= Strip String ${TEST_MESSAGE} mode=right
Set Test Message ${message}
END
${timed_out}= Run Keyword If Timeout Occurred Set Variable True
IF ${timed_out} RETURN
IF ${CREATE_SNAPSHOT_ON_FAIL}
Run Keyword If Test Failed
... Create Snapshot Of Failed Test
END
Close Log File
IF "${SAVE_LOGS_WHEN}" == "Always" or ${failed}
Print Log Saved Message
ELSE
Remove Log
END
IF ${HOLD_ON_ERROR}
${res}= Run Keyword If Test Failed
... Run Keyword And Ignore Error
... Import Library Dialogs
Run Keyword If Test Failed Run Keywords
... Run Keyword If '${res[0]}' == 'FAIL' Log Couldn't load the Dialogs library - interactive debugging is not possible console=True
... AND Run Keyword If '${res[0]}' != 'FAIL' Open GUI
... AND Run Keyword If '${res[0]}' != 'FAIL' Pause Execution Test failed. Press OK once done debugging.
... AND Run Keyword If '${res[0]}' != 'FAIL' Close GUI
END
Reset Emulation
Hot Spot
Handle Hot Spot ${HOTSPOT_ACTION}
Start Profiler
${test_name}= Get Sanitized Test Name
${traces_dir}= Set Variable ${RESULTS_DIRECTORY}/traces
Create Directory ${traces_dir}
${trace_path}= Set Variable ${traces_dir}/${test_name}
Log To Console !!!!! Writing nettrace to "${trace_path}.nettrace"
Log To Console !!!!! Writing speedscope trace to "${trace_path}.speedscope.json"
# note that those logs may not be bundled with log and snapshot saving info
${proc}= Start Process dotnet trace collect -p ${RENODE_PID} --format Speedscope -o ${trace_path}.nettrace
Set Test Variable ${PROFILER_PROCESS} ${proc}
Stop Profiler
IF ${PROFILER_PROCESS}
Terminate Process ${PROFILER_PROCESS}
Set Test Variable ${PROFILER_PROCESS} None
END
Dump Registers Range
[Tags] robot:private
[Arguments] ${Device} ${End} ${Start}=0
${Dump}= Create Dictionary
FOR ${index} IN RANGE ${Start} ${End}+1 4
${RegValue}= Execute Command ${Device} ReadDoubleWord ${index}
${RegValue}= Remove String ${RegValue} \n # Remove newlines to make diff output more readable
Set To Dictionary ${Dump} ${index} ${RegValue}
END
RETURN ${Dump}
Dump Devices Registers
[Documentation] Dump devices' registers values into a dictionary of dictionary
... ``{'device':{reg_offset:reg_value}}`` from a dictionary of ``devices:list of
... offset ranges``.
...
... Dumping registers when there is a gap in the model may work and simplify the
... test case.
...
... Example:
... | ${RegistersToDump} = | Create Dictionary | adc1=${{ [(0x0, 0xC4), (0x308, 0x308)] }} |
... | &{Dump} = | Dump Devices Registers | ${RegistersToDump} |
...
... Please not the usage of inline python evaluation ``${{}}`` to keep tuples
... instead of having strings.
[Arguments] ${DevicesAndRanges}
${Dump}= Create Dictionary
FOR ${Device} ${Ranges} IN &{DevicesAndRanges}
FOR ${Range} IN @{Ranges}
${RegsDump}= Dump Registers Range ${Device} ${Range}[1] ${Range}[0]
Set To Dictionary ${Dump} ${Device}=${RegsDump}
Log Dictionary ${Dump}
END
END
RETURN ${Dump}
Devices Registers Dump Should Be Equal
[Documentation] Compare dumps returned by Dump Devices Registers.
[Arguments] ${DumpA} ${DumpB} ${NameDumpA}=DumpA ${NameDumpB}=DumpB
${DevicesA}= Get Dictionary Keys ${DumpA}
${DevicesB}= Get Dictionary Keys ${DumpB}
TRY
Dictionaries Should Be Equal ${DumpA} ${DumpB}
EXCEPT
# On error, printing the whole device:'registers_dump' dictionary entry is hard to read. So
# instead, let's compare device by device to print the first
FOR ${device} IN @{DevicesA}
${DeviceDumpA}= Get From Dictionary dictionary=${DumpA} key=${device}
${DeviceDumpB}= Get From Dictionary dictionary=${DumpB} key=${device}
TRY
Dictionaries Should Be Equal ${DeviceDumpA} ${DeviceDumpB}
EXCEPT
CONTINUE
END
END
FAIL ${NameDumpA} and ${NameDumpB} dumps differ, see logs of previous for loop for
... more details on which entries are different.
END