1*** Variables ***
2${COVERAGE_TEST_BINARY_URL}         https://dl.antmicro.com/projects/renode/coverage-tests/coverage-test.elf-s_3603888-0f7cfe992528c2576a9ac6a4dcc3a41b03d1d6eb
3${COVERAGE_TEST_CODE_URL}           https://dl.antmicro.com/projects/renode/coverage-tests/main.c
4${COVERAGE_TEST_CODE_FILENAME}      main.c
5${EXECUTION_TRACER}                 ${RENODETOOLS}/execution_tracer/execution_tracer_reader.py
6${TRACED_CPU}                       cpu1
7&{COVERAGE_REPORT_LINES}            # pairs of line number and expected executions
8...                                 6=28
9...                                 7=2828
10...                                 8=2800
11...                                 10=28
12...                                 12=32
13...                                 13=3232
14...                                 14=3200
15...                                 16=32
16...                                 18=2
17...                                 19=202
18...                                 20=200
19...                                 22=2
20...                                 24=1
21...                                 25=1
22...                                 26=101
23...                                 27=100
24...                                 30=1
25...                                 32=101
26...                                 33=100
27...                                 34=32
28...                                 36=100
29...                                 37=28
30...                                 41=1
31...                                 43=1
32...                                 44=1
33
34@{COVERAGE_REPORT_LCOV}
35...                                 TN:
36...                                 SF:main.c
37...                                 DA:6,28
38...                                 DA:7,2828
39...                                 DA:8,2800
40...                                 DA:10,28
41...                                 DA:12,32
42...                                 DA:13,3232
43...                                 DA:14,3200
44...                                 DA:16,32
45...                                 DA:18,2
46...                                 DA:19,202
47...                                 DA:20,200
48...                                 DA:22,2
49...                                 DA:24,1
50...                                 DA:25,1
51...                                 DA:26,101
52...                                 DA:27,100
53...                                 DA:30,1
54...                                 DA:32,101
55...                                 DA:33,100
56...                                 DA:34,32
57...                                 DA:36,100
58...                                 DA:37,28
59...                                 DA:41,1
60...                                 DA:43,1
61...                                 DA:44,1
62...                                 end_of_record
63
64*** Keywords ***
65Execute Python Script
66    [Arguments]                     ${path}  ${args}
67    ${all_args}=                    Create List  ${path}  @{args}
68
69    ${output}=                      Evaluate  subprocess.run([sys.executable] + ${all_args})  sys,subprocess
70    RETURN                          ${output}
71
72Download File And Rename
73    [Arguments]                     ${url}  ${filename}
74    ${temporary_file}=              Download File  ${url}
75    ${path_fragments}=              Split Path  ${temporary_file}
76    ${new_path}=                    Join Path  ${path_fragments}[0]  ${filename}
77    Move File                       ${temporary_file}  ${new_path}
78    RETURN                          ${new_path}
79
80Create Platform
81    [Arguments]                     ${executable}
82    Execute Command                 $bin=@${executable}
83    Execute Command                 i @scripts/single-node/kendryte_k210.resc
84    Execute Command                 cpu2 IsHalted true
85
86Trace Execution
87    [Arguments]                     ${executable}  ${compress}
88
89    Create Platform                 ${executable}
90
91    ${trace_file}=                  Allocate Temporary File
92
93    Execute Command                 ${TRACED_CPU} CreateExecutionTracing "trace" @${trace_file} PC true ${compress}
94    Execute Command                 emulation RunFor "0.017"
95    Execute Command                 ${TRACED_CPU} DisableExecutionTracing
96    RETURN                          ${trace_file}
97
98Line Should Report Executions
99    [Arguments]                     ${line}  ${executions}
100    Should Start With               ${line}  ${executions}:  strip_spaces=True  collapse_spaces=True
101
102Should Report Proper Coverage
103    [Arguments]                     ${report}  ${expected_lines}
104    FOR  ${expected_line}  IN  &{expected_lines}
105        ${line_index}=                  Evaluate  ${expected_line}[0] - 1
106        Line Should Report Executions   ${report}[${line_index}]  ${expected_line}[1]
107    END
108
109    FOR  ${line_index}  ${report_line}  IN ENUMERATE  @{report}
110        ${line_number}=                 Evaluate  str(${line_index} + 1)
111        IF  ${{ $line_number not in $COVERAGE_REPORT_LINES }}
112            Line Should Report Executions   ${report_line}  0
113        END
114    END
115
116Should Report Proper Coverage LCOV
117    [Arguments]                     ${report}  ${expected_lines}
118    Should Be Equal As Strings      ${report}  ${expected_lines}  strip_spaces=True
119
120Trace And Report Coverage
121    [Arguments]                     ${is_legacy}  ${compress}=False
122    ${coverage_file}=               Allocate Temporary File
123    ${binary_file}=                 Download File  ${COVERAGE_TEST_BINARY_URL}
124    ${code_file}=                   Download File And Rename  ${COVERAGE_TEST_CODE_URL}  ${COVERAGE_TEST_CODE_FILENAME}
125
126    ${trace}=                       Trace Execution  ${COVERAGE_TEST_BINARY_URL}  ${compress}
127    ${script_args}=                 Create List
128
129    IF  ${compress} == True
130        Append To List                  ${script_args}  --decompress
131    END
132
133    Append To List                  ${script_args}
134    ...                             coverage
135    ...                             ${trace}
136    ...                             --binary
137    ...                             ${binary_file}
138    ...                             --sources
139    ...                             ${code_file}
140    ...                             --output
141    ...                             ${coverage_file}
142
143    IF  ${is_legacy} == True
144        Append To List              ${script_args}  --legacy
145    END
146
147    Execute Python Script           ${EXECUTION_TRACER}  ${script_args}
148
149    ${coverage_report_content}=     Get File  ${coverage_file}
150    ${coverage_report}=             Split To Lines  ${coverage_report_content}
151    IF  ${is_legacy} == True
152        Should Report Proper Coverage       ${coverage_report}  ${COVERAGE_REPORT_LINES}
153    ELSE
154        # The slice is necessary to omit "filename", which is expected to differ (since the absolute paths are never the same in the temp directory)
155        Should Report Proper Coverage LCOV  ${coverage_report}[2:]  ${COVERAGE_REPORT_LCOV}[2:]
156    END
157
158*** Test Cases ***
159Trace And Report Coverage
160    Trace And Report Coverage       False
161
162Trace And Report Coverage In Legacy Format
163    Trace And Report Coverage       True
164
165Trace With Compressed Output And Report Coverage
166    Trace And Report Coverage       False  True
167
168Trace With Compressed Output And Report Coverage In Legacy Format
169    Trace And Report Coverage       True  True
170