ceedling 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/GIT_COMMIT_SHA +1 -1
- data/Gemfile +4 -0
- data/Gemfile.lock +2 -0
- data/README.md +4 -1
- data/docs/Changelog.md +41 -0
- data/docs/KnownIssues.md +3 -0
- data/docs/mkdocs/configuration/project-file.md +25 -7
- data/docs/mkdocs/configuration/reference/cexception.md +1 -1
- data/docs/mkdocs/configuration/reference/cmock.md +1 -1
- data/docs/mkdocs/configuration/reference/unity.md +1 -1
- data/docs/mkdocs/getting-started/quick-start.md +11 -8
- data/docs/mkdocs/plugins/gcov/gcovr.md +329 -189
- data/docs/mkdocs/plugins/gcov/reportgenerator.md +113 -31
- data/docs/mkdocs/reference/gcov-plugin.md +29 -6
- data/docs/mkdocs/snapshot/plugins/gcov/config/defaults.yml +0 -1
- data/lib/ceedling/c_extractor/c_extractor_declarations.rb +11 -10
- data/lib/ceedling/c_extractor/c_extractor_preprocessing.rb +39 -2
- data/lib/ceedling/generators/generator_test_results_backtrace.rb +21 -11
- data/lib/ceedling/generators/generator_test_runner.rb +5 -1
- data/lib/ceedling/plugins/plugin_reportinator.rb +9 -0
- data/lib/ceedling/plugins/report_tests_stdout_plugin.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +6 -1
- data/lib/ceedling/preprocess/preprocessinator_reconstructor.rb +18 -5
- data/lib/version.rb +1 -1
- data/plugins/gcov/config/defaults.yml +0 -1
- data/plugins/gcov/lib/console_reportinator.rb +7 -0
- data/plugins/gcov/lib/gcov.rb +64 -26
- data/plugins/gcov/lib/gcovr_reportinator.rb +91 -47
- data/plugins/gcov/lib/reportgenerator_reportinator.rb +10 -6
- data/plugins/valgrind/lib/valgrind.rb +1 -1
- data/site-local/configuration/project-file.html +78 -8
- data/site-local/configuration/reference/cexception.html +5 -5
- data/site-local/configuration/reference/cmock.html +5 -5
- data/site-local/configuration/reference/unity.html +5 -5
- data/site-local/getting-started/quick-start.html +13 -9
- data/site-local/plugins/gcov/gcovr.html +1220 -255
- data/site-local/plugins/gcov/reportgenerator.html +404 -46
- data/site-local/reference/gcov-plugin.html +48 -10
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/plugins/gcov/config/defaults.yml +0 -1
- data/spec/support/system/system_context.rb +7 -3
- data/spec/system/deployment_as_gem_spec.rb +2 -0
- data/spec/system/deployment_as_vendor_spec.rb +2 -0
- data/spec/system/gcov_deployment_spec.rb +3 -0
- data/spec/system/support/common_test_cases.rb +42 -0
- data/spec/system/support/gcov_common_test_cases.rb +70 -0
- data/spec/units/c_extractor/c_extractor_declarations_spec.rb +16 -0
- data/spec/units/c_extractor/c_extractor_integration_spec.rb +53 -0
- data/spec/units/c_extractor/c_extractor_preprocessing_spec.rb +45 -0
- data/spec/units/generators/generator_partials_spec.rb +98 -0
- data/spec/units/generators/generator_test_results_backtrace_spec.rb +77 -0
- data/spec/units/generators/generator_test_runner_spec.rb +23 -0
- data/spec/units/plugin_reportinator_spec.rb +38 -0
- data/spec/units/preprocess/preprocessinator_line_marker_includes_extractor_spec.rb +64 -0
- data/spec/units/preprocess/preprocessinator_reconstructor_spec.rb +74 -0
- metadata +6 -2
|
@@ -4,55 +4,137 @@ The `ReportGenerator` utility may be configured with the following configuration
|
|
|
4
4
|
|
|
5
5
|
All generated reports are found in `<build root>/artifacts/gcov/ReportGenerator/`.
|
|
6
6
|
|
|
7
|
+
## Example configuration
|
|
8
|
+
|
|
7
9
|
```yaml
|
|
8
10
|
:gcov:
|
|
9
11
|
:report_generator:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
:
|
|
12
|
+
:history_directory: build/artifacts/gcov/history
|
|
13
|
+
:file_filters: "-./vendor/*;-./build/*;-./test/*;+./src/*"
|
|
14
|
+
:verbosity: Warning
|
|
15
|
+
:tag: "release-1.4.0"
|
|
16
|
+
:num_parallel_threads: 4
|
|
17
|
+
:gcov_exclude:
|
|
18
|
+
- some_excluded_file
|
|
19
|
+
:custom_args:
|
|
20
|
+
- "-title:MyProject"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Plugin configuration
|
|
24
|
+
|
|
25
|
+
### `:history_directory`
|
|
26
|
+
|
|
27
|
+
Optional directory for storing persistent coverage information. Can be used
|
|
28
|
+
in future reports to show coverage evolution.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### `:plugins`
|
|
33
|
+
|
|
34
|
+
Optional plugin files for custom reports or custom history storage (separated
|
|
35
|
+
by semicolon).
|
|
36
|
+
|
|
37
|
+
**Example:** `plugin.dll;*.dll`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### `:assembly_filters`
|
|
42
|
+
|
|
43
|
+
Optional list of assemblies that should be included or excluded in the
|
|
44
|
+
report (separated by semicolon). Exclusion filters take precedence over
|
|
45
|
+
inclusion filters. Wildcards are allowed, but not regular expressions.
|
|
46
|
+
|
|
47
|
+
**Example:** `+<included>;-<excluded>`
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### `:class_filters`
|
|
52
|
+
|
|
53
|
+
Optional list of classes that should be included or excluded in the report
|
|
54
|
+
(separated by semicolon). Exclusion filters take precedence over inclusion
|
|
55
|
+
filters. Wildcards are allowed, but not regular expressions.
|
|
56
|
+
|
|
57
|
+
**Example:** `+<included>;-<excluded>`
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### `:file_filters`
|
|
62
|
+
|
|
63
|
+
Optional list of files that should be included or excluded in the report
|
|
64
|
+
(separated by semicolon). Exclusion filters take precedence over inclusion
|
|
65
|
+
filters. Wildcards are allowed, but not regular expressions. Ceedling places
|
|
66
|
+
your own patterns first, ahead of the exclusions it generates automatically
|
|
67
|
+
for test paths, the build root, and (when Partials are in use) Partial
|
|
68
|
+
source files, so your patterns take precedence.
|
|
13
69
|
|
|
14
|
-
|
|
15
|
-
:plugins: <plugin.dll>;<*.dll>
|
|
70
|
+
**Example:** `"-./vendor/*;-./build/*;-./test/*;-./lib/*;+./src/*"`
|
|
16
71
|
|
|
17
|
-
|
|
18
|
-
# Exclusion filters take precedence over inclusion filters.
|
|
19
|
-
# Wildcards are allowed, but not regular expressions.
|
|
20
|
-
:assembly_filters: +<included>;-<excluded>
|
|
72
|
+
---
|
|
21
73
|
|
|
22
|
-
|
|
23
|
-
# Exclusion filters take precedence over inclusion filters.
|
|
24
|
-
# Wildcards are allowed, but not regular expressions.
|
|
25
|
-
:class_filters: +<included>;-<excluded>
|
|
74
|
+
### `:verbosity`
|
|
26
75
|
|
|
27
|
-
|
|
28
|
-
# Exclusion filters take precedence over inclusion filters.
|
|
29
|
-
# Wildcards are allowed, but not regular expressions.
|
|
30
|
-
# Example: "-./vendor/*;-./build/*;-./test/*;-./lib/*;+./src/*"
|
|
31
|
-
:file_filters: +<included>;-<excluded>
|
|
76
|
+
The verbosity level of the log messages.
|
|
32
77
|
|
|
33
|
-
|
|
34
|
-
# Values: Verbose, Info, Warning, Error, Off (defaults to Warning)
|
|
35
|
-
:verbosity: <level>
|
|
78
|
+
**Values:** `Verbose`, `Info`, `Warning`, `Error`, `Off`
|
|
36
79
|
|
|
37
|
-
|
|
38
|
-
:tag: <tag>
|
|
80
|
+
**Default:** `Warning`
|
|
39
81
|
|
|
40
|
-
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### `:tag`
|
|
85
|
+
|
|
86
|
+
Optional tag or build version.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### `:gcov_exclude`
|
|
91
|
+
|
|
92
|
+
Optional list of one or more regular expressions to exclude gcov notes
|
|
93
|
+
(`.gcno`) files that match these filters from coverage processing — these
|
|
94
|
+
files are never run through `gcov` at all. A trailing `.gcov` or `.gcno`
|
|
95
|
+
suffix on a pattern is stripped automatically, so either form works.
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
:gcov:
|
|
99
|
+
:report_generator:
|
|
41
100
|
:gcov_exclude:
|
|
42
101
|
- <regex>
|
|
43
102
|
- ...
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Default:** `[]`
|
|
44
106
|
|
|
45
|
-
|
|
46
|
-
:threads: <count>
|
|
107
|
+
---
|
|
47
108
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
109
|
+
### `:num_parallel_threads`
|
|
110
|
+
|
|
111
|
+
Optionally set the number of threads ReportGenerator uses in parallel. Drives
|
|
112
|
+
both of ReportGenerator's own `numberOfReportsParsedInParallel` and
|
|
113
|
+
`numberOfReportsMergedInParallel` settings together.
|
|
114
|
+
|
|
115
|
+
**Default:** unset (ReportGenerator's own default applies)
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### `:custom_args`
|
|
120
|
+
|
|
121
|
+
Optional list of one or more command line arguments to pass to Report
|
|
122
|
+
Generator. Useful for configuring Risk Hotspots and other settings not
|
|
123
|
+
covered by the options above. See the
|
|
124
|
+
[ReportGenerator settings wiki](https://github.com/danielpalme/ReportGenerator/wiki/Settings).
|
|
125
|
+
|
|
126
|
+
Note: This can be accomplished with Ceedling's tool configuration options
|
|
127
|
+
outside of plugin configuration but is supported here to collect
|
|
128
|
+
configuration options in one place.
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
:gcov:
|
|
132
|
+
:report_generator:
|
|
53
133
|
:custom_args:
|
|
54
134
|
- <argument>
|
|
55
135
|
- ...
|
|
56
136
|
```
|
|
57
137
|
|
|
138
|
+
**Default:** `[]`
|
|
139
|
+
|
|
58
140
|
<br/><br/>
|
|
@@ -213,8 +213,24 @@ Exit with status 4 if total branch coverage is below this percentage.
|
|
|
213
213
|
Exit with status 8 if total decision coverage is below this percentage.
|
|
214
214
|
(`gcovr --fail-under-decision`)
|
|
215
215
|
|
|
216
|
+
`gcovr` treats `--fail-under-decision` as a no-op without `--decisions` also
|
|
217
|
+
present — setting this option implies `:decisions` (below) automatically.
|
|
218
|
+
|
|
216
219
|
**Values:** `1`–`100`
|
|
217
220
|
|
|
221
|
+
**Requires:** `gcovr` 7.0 or higher
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### `:decisions`
|
|
226
|
+
|
|
227
|
+
Report the decision coverage. For HTML, JSON, and the summary report.
|
|
228
|
+
(`gcovr --decisions`)
|
|
229
|
+
|
|
230
|
+
Implied automatically whenever `:fail_under_decision` is set.
|
|
231
|
+
|
|
232
|
+
**Requires:** `gcovr` 5.1 or higher
|
|
233
|
+
|
|
218
234
|
---
|
|
219
235
|
|
|
220
236
|
### `:fail_under_function`
|
|
@@ -246,21 +262,26 @@ Source file character encoding. (`gcovr --source-encoding`)
|
|
|
246
262
|
### `:branches`
|
|
247
263
|
|
|
248
264
|
Report branch coverage instead of line coverage. Applies to text reports only.
|
|
249
|
-
|
|
265
|
+
Uses `gcovr --txt-metric branch` on `gcovr` 7.0+ (`--branches` is deprecated as
|
|
266
|
+
of 7.0, though still functional); `gcovr --branches` below it.
|
|
250
267
|
|
|
251
268
|
---
|
|
252
269
|
|
|
253
270
|
### `:sort_uncovered`
|
|
254
271
|
|
|
255
272
|
Sort report entries by increasing number of uncovered lines. Applies to text
|
|
256
|
-
and HTML reports.
|
|
273
|
+
and HTML reports. Uses `gcovr --sort uncovered-number` on `gcovr` 7.0+
|
|
274
|
+
(`--sort-uncovered` is deprecated as of 7.0, though still functional);
|
|
275
|
+
`gcovr --sort-uncovered` below it.
|
|
257
276
|
|
|
258
277
|
---
|
|
259
278
|
|
|
260
279
|
### `:sort_percentage`
|
|
261
280
|
|
|
262
281
|
Sort report entries by increasing percentage of uncovered lines. Applies to
|
|
263
|
-
text and HTML reports.
|
|
282
|
+
text and HTML reports. Uses `gcovr --sort uncovered-percent` on `gcovr` 7.0+
|
|
283
|
+
(`--sort-percentage` is deprecated as of 7.0, though still functional);
|
|
284
|
+
`gcovr --sort-percentage` below it.
|
|
264
285
|
|
|
265
286
|
---
|
|
266
287
|
|
|
@@ -552,11 +573,13 @@ are excluded from report generation.
|
|
|
552
573
|
|
|
553
574
|
---
|
|
554
575
|
|
|
555
|
-
### `:
|
|
576
|
+
### `:num_parallel_threads`
|
|
556
577
|
|
|
557
|
-
Number of parallel threads to use during report generation.
|
|
578
|
+
Number of parallel threads to use during report generation. Drives both
|
|
579
|
+
ReportGenerator's own `numberOfReportsParsedInParallel` and
|
|
580
|
+
`numberOfReportsMergedInParallel` settings together.
|
|
558
581
|
|
|
559
|
-
**Default:**
|
|
582
|
+
**Default:** unset (ReportGenerator's own default applies)
|
|
560
583
|
|
|
561
584
|
---
|
|
562
585
|
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
|
|
28
28
|
:report_generator:
|
|
29
29
|
:verbosity: Warning # Default verbosity
|
|
30
|
-
:collection_paths_source: [] # Explicitly defined as default empty array to simplify option validation code
|
|
31
30
|
:custom_args: [] # Explicitly defined as default empty array to simplify option validation code
|
|
32
31
|
:gcov_exclude: [] # Explicitly defined as default empty array to simplify option validation code
|
|
33
32
|
...
|
|
@@ -402,16 +402,17 @@ class CExtractorDeclarations
|
|
|
402
402
|
return $1.strip
|
|
403
403
|
end
|
|
404
404
|
|
|
405
|
-
# Find the name in the text and take everything before it (including pointer specifiers)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
#
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
405
|
+
# Find the name in the text and take everything before it (including pointer specifiers).
|
|
406
|
+
# A plain rindex(name) would find the last substring occurrence of `name` anywhere in
|
|
407
|
+
# text, even inside an unrelated longer identifier that merely ends with it (e.g. `name`
|
|
408
|
+
# "count" inside a type-side identifier like "recount") -- \b anchors this to a whole
|
|
409
|
+
# identifier occurrence. Greedy `.*` in a single match (not scan) naturally finds the
|
|
410
|
+
# rightmost such occurrence, since it consumes as much as possible before backtracking
|
|
411
|
+
# just enough to let the trailing \bname\b still match.
|
|
412
|
+
match = text.match(/\A(.*)\b#{Regexp.escape(name)}\b/m)
|
|
413
|
+
return nil if match.nil?
|
|
414
|
+
|
|
415
|
+
type_part = match[1]
|
|
415
416
|
type_part.strip
|
|
416
417
|
end
|
|
417
418
|
|
|
@@ -241,9 +241,46 @@ class CExtractorPreprocessing
|
|
|
241
241
|
text = scanner.scan(/#/)
|
|
242
242
|
|
|
243
243
|
until scanner.eos?
|
|
244
|
-
|
|
244
|
+
# '/' is excluded here (alongside the quote/backslash/newline characters
|
|
245
|
+
# already excluded) so a comment marker is never swallowed into this plain
|
|
246
|
+
# literal run -- it has to be seen and dispatched on its own below, before
|
|
247
|
+
# any '"' or "'" inside the comment's own text gets mistaken for the start
|
|
248
|
+
# of a string/char literal (see the // and /* branches for why that matters).
|
|
249
|
+
text << (scanner.scan(/[^"'\\\n\/]*/) || '')
|
|
250
|
+
|
|
251
|
+
if scanner.scan(%r{//})
|
|
252
|
+
# A trailing line comment (e.g. "// don't change this") can contain an
|
|
253
|
+
# apostrophe or quote that isn't a literal delimiter at all. Consumed the
|
|
254
|
+
# ordinary way, that stray quote would send skip_c_string hunting for a
|
|
255
|
+
# closing match, straight through this directive's own newline and into
|
|
256
|
+
# whatever follows -- silently merging the next #define into this one.
|
|
257
|
+
# Comment content is captured verbatim and never scanned for literals.
|
|
258
|
+
#
|
|
259
|
+
# A '\' immediately before the physical newline still splices lines here,
|
|
260
|
+
# same as everywhere else in a directive (line splicing is a translation
|
|
261
|
+
# phase that happens before comments are stripped), so the comment -- and
|
|
262
|
+
# the directive -- keeps going onto the next physical line rather than
|
|
263
|
+
# ending at that newline.
|
|
264
|
+
before = scanner.pos - 2
|
|
265
|
+
loop do
|
|
266
|
+
scanner.scan(/[^\\\n]*/)
|
|
267
|
+
break if scanner.eos?
|
|
268
|
+
break unless scanner.scan(/\\\n/) || scanner.scan(/\\/)
|
|
269
|
+
end
|
|
270
|
+
text << scanner.string[before...scanner.pos]
|
|
271
|
+
|
|
272
|
+
elsif scanner.scan(%r{/\*})
|
|
273
|
+
# A block comment can legitimately span physical lines without ending the
|
|
274
|
+
# directive (only an un-commented newline does that) -- its content, quotes
|
|
275
|
+
# included, is likewise never scanned for literals, only for its own close.
|
|
276
|
+
before = scanner.pos - 2
|
|
277
|
+
scanner.skip_until(%r{\*/}) || scanner.terminate
|
|
278
|
+
text << scanner.string[before...scanner.pos]
|
|
279
|
+
|
|
280
|
+
elsif scanner.scan(%r{/})
|
|
281
|
+
text << '/'
|
|
245
282
|
|
|
246
|
-
|
|
283
|
+
elsif (ch = scanner.peek(1)) == '"' || ch == "'"
|
|
247
284
|
before = scanner.pos
|
|
248
285
|
@c_extractor_code_text.skip_c_string(scanner, ch)
|
|
249
286
|
text << scanner.string[before...scanner.pos]
|
|
@@ -66,13 +66,17 @@ class GeneratorTestResultsBacktrace
|
|
|
66
66
|
# Attribute each group member its own real result line, if Unity printed one
|
|
67
67
|
group.each do |test_case|
|
|
68
68
|
case crash_result[:output]
|
|
69
|
-
# Success test case
|
|
70
|
-
|
|
69
|
+
# Success test case -- tolerates a trailing duration suffix (e.g. `PASS (12 ms)`,
|
|
70
|
+
# UNITY_INCLUDE_EXEC_TIME), matching the real format generator_test_results.rb's
|
|
71
|
+
# own parser already recognizes for it.
|
|
72
|
+
when /(^#{Regexp.escape(filename)}:\d+:#{Regexp.escape(test_case[:test])}:PASS(\s\(.*ms\))?\s*$)/
|
|
71
73
|
group_results[:passed] += 1
|
|
72
74
|
group_results[:output] << $1
|
|
73
75
|
|
|
74
|
-
# Ignored test case
|
|
75
|
-
|
|
76
|
+
# Ignored test case -- tolerates a trailing message (TEST_IGNORE_MESSAGE), same as
|
|
77
|
+
# FAIL below. Before this fix, a message-carrying ignore fell through to "unresolved"
|
|
78
|
+
# and was misreported as crash evidence -- IGNORE was only recognized bare.
|
|
79
|
+
when /(^#{Regexp.escape(filename)}:\d+:#{Regexp.escape(test_case[:test])}:IGNORE(:.+)?\s*$)/
|
|
76
80
|
group_results[:ignored] += 1
|
|
77
81
|
group_results[:output] << $1
|
|
78
82
|
|
|
@@ -91,9 +95,11 @@ class GeneratorTestResultsBacktrace
|
|
|
91
95
|
# Prefer whichever unresolved member's own C symbol is actually named in the gdb
|
|
92
96
|
# backtrace (works regardless of position in the group); fall back to the first
|
|
93
97
|
# unresolved member if no member's symbol can be found in the transcript (e.g. a
|
|
94
|
-
# brief crash report with no frame information at all).
|
|
98
|
+
# brief crash report with no frame information at all). \b anchors the symbol so a
|
|
99
|
+
# shorter unresolved symbol that's merely a suffix of a longer one actually named in
|
|
100
|
+
# the frame (e.g. "foo" vs "my_foo") can't steal the attribution.
|
|
95
101
|
crashed_case = unresolved.find do |tc|
|
|
96
|
-
crash_result[:output].match?(
|
|
102
|
+
crash_result[:output].match?( /\b#{Regexp.escape(tc[:symbol])}\s*\(\)\sat/ )
|
|
97
103
|
end
|
|
98
104
|
crashed_case ||= unresolved.first
|
|
99
105
|
|
|
@@ -260,13 +266,17 @@ class GeneratorTestResultsBacktrace
|
|
|
260
266
|
# Attribute each group member its own real result line, if Unity printed one
|
|
261
267
|
group.each do |test_case|
|
|
262
268
|
case crash_result[:output]
|
|
263
|
-
# Success test case
|
|
264
|
-
|
|
269
|
+
# Success test case -- tolerates a trailing duration suffix (e.g. `PASS (12 ms)`,
|
|
270
|
+
# UNITY_INCLUDE_EXEC_TIME), matching the real format generator_test_results.rb's
|
|
271
|
+
# own parser already recognizes for it.
|
|
272
|
+
when /(^#{Regexp.escape(filename)}:\d+:#{Regexp.escape(test_case[:test])}:PASS(\s\(.*ms\))?\s*$)/
|
|
265
273
|
group_results[:passed] += 1
|
|
266
274
|
group_results[:output] << $1
|
|
267
275
|
|
|
268
|
-
# Ignored test case
|
|
269
|
-
|
|
276
|
+
# Ignored test case -- tolerates a trailing message (TEST_IGNORE_MESSAGE), same as
|
|
277
|
+
# FAIL below. Before this fix, a message-carrying ignore fell through to "unresolved"
|
|
278
|
+
# and was misreported as crash evidence -- IGNORE was only recognized bare.
|
|
279
|
+
when /(^#{Regexp.escape(filename)}:\d+:#{Regexp.escape(test_case[:test])}:IGNORE(:.+)?\s*$)/
|
|
270
280
|
group_results[:ignored] += 1
|
|
271
281
|
group_results[:output] << $1
|
|
272
282
|
|
|
@@ -450,7 +460,7 @@ class GeneratorTestResultsBacktrace
|
|
|
450
460
|
output.lines.filter_map do |line|
|
|
451
461
|
line = line.strip
|
|
452
462
|
next if line.empty?
|
|
453
|
-
next if line =~ /^#{filename}.+:(PASS|FAIL|IGNORE)/
|
|
463
|
+
next if line =~ /^#{Regexp.escape(filename)}.+:(PASS|FAIL|IGNORE)/
|
|
454
464
|
line
|
|
455
465
|
end
|
|
456
466
|
end
|
|
@@ -129,7 +129,11 @@ class GeneratorTestRunner
|
|
|
129
129
|
break if remaining.empty?
|
|
130
130
|
|
|
131
131
|
next_case = remaining.first
|
|
132
|
-
|
|
132
|
+
# Escaped (a raw test name can contain regex metacharacters) and \b-anchored on both
|
|
133
|
+
# sides so an unrelated line that merely contains this test's name as a substring --
|
|
134
|
+
# e.g. a helper function like `reset_test_ab_state()` sitting before `test_ab` itself
|
|
135
|
+
# -- can't steal its line number and cascade misalignment to every case after it.
|
|
136
|
+
if (line =~ /\b#{Regexp.escape(next_case[:test])}\b/)
|
|
133
137
|
next_case[:line_number] = line_num
|
|
134
138
|
remaining.shift
|
|
135
139
|
end
|
|
@@ -95,6 +95,15 @@ class PluginReportinator
|
|
|
95
95
|
return aggregated_results
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
# A build's own test results -- pass or fail -- are core information a user
|
|
99
|
+
# silencing routine build chatter still wants to see; ERRORS is the floor
|
|
100
|
+
# for both, not just for a failing run. Centralized here so every plugin
|
|
101
|
+
# printing post-build test results (report_tests_stdout_plugin, gcov,
|
|
102
|
+
# valgrind) agrees on the same answer instead of each hardcoding its own.
|
|
103
|
+
def test_results_floor_verbosity
|
|
104
|
+
Verbosity::ERRORS
|
|
105
|
+
end
|
|
106
|
+
|
|
98
107
|
def run_test_results_report(hash, verbosity=Verbosity::NORMAL)
|
|
99
108
|
if @test_results_template.nil?
|
|
100
109
|
raise CeedlingException.new( "No test results report template has been set." )
|
|
@@ -50,7 +50,7 @@ class ReportTestsStdoutPlugin < Plugin
|
|
|
50
50
|
|
|
51
51
|
results = @plugin_reportinator.assemble_test_results( @result_list )
|
|
52
52
|
hash = { :context => TEST_SYM, :results => results }
|
|
53
|
-
verbosity =
|
|
53
|
+
verbosity = @plugin_reportinator.test_results_floor_verbosity
|
|
54
54
|
|
|
55
55
|
# Print unit test suite results
|
|
56
56
|
@plugin_reportinator.run_test_results_report( hash, verbosity )
|
|
@@ -82,7 +82,12 @@ require 'set'
|
|
|
82
82
|
|
|
83
83
|
# Parse GCC preprocessor output (from -fdirectives-only) to extract system include directives
|
|
84
84
|
class PreprocessinatorLineMarkerIncludesExtractor
|
|
85
|
-
|
|
85
|
+
# Leading whitespace is tolerated (`^\s*`, not just `^`): GCC's -fdirectives-only output
|
|
86
|
+
# replaces a top-level #include with a line marker that inherits that #include's own
|
|
87
|
+
# original indentation (GH #1268) -- an indented `#include "x.h"` produces an indented
|
|
88
|
+
# ` # 1 "x.h" 1`, not the flush-left marker every OTHER marker GCC generates uses.
|
|
89
|
+
# Without this, such an include is silently missing from the extracted list entirely.
|
|
90
|
+
LINE_MARKER_REGEX = /^\s*#\s+(\d+)\s+"([^"]+)"(?:\s+(\d+(?:\s+\d+)*))?$/ unless const_defined?(:LINE_MARKER_REGEX)
|
|
86
91
|
|
|
87
92
|
SYSTEM = :system unless const_defined?(:SYSTEM)
|
|
88
93
|
USER = :user unless const_defined?(:USER)
|
|
@@ -236,8 +236,15 @@ class PreprocessinatorReconstructor
|
|
|
236
236
|
def extract_macro_defs(file_contents, include_guard)
|
|
237
237
|
macro_definitions = extract_multiline_directives( file_contents, 'define' )
|
|
238
238
|
|
|
239
|
-
# Remove an include guard if provided
|
|
240
|
-
|
|
239
|
+
# Remove an include guard if provided. A plain substring test here would also reject
|
|
240
|
+
# any ordinary macro whose name or value happens to contain the guard string -- e.g.
|
|
241
|
+
# guard RTC_H matching inside RTC_HOUR_SECONDS' own name, or inside RTC_DAY_SECONDS'
|
|
242
|
+
# value, which references RTC_HOUR_SECONDS (GH #1266). Anchoring to "#define <guard>"
|
|
243
|
+
# followed by whitespace or end-of-line only matches the guard definition itself.
|
|
244
|
+
if !include_guard.nil?
|
|
245
|
+
include_guard_regex = /^\s*#\s*define\s+#{Regexp.escape(include_guard)}(?:\s|$)/
|
|
246
|
+
macro_definitions.reject! {|macro| macro =~ include_guard_regex }
|
|
247
|
+
end
|
|
241
248
|
|
|
242
249
|
return macro_definitions
|
|
243
250
|
end
|
|
@@ -271,10 +278,16 @@ class PreprocessinatorReconstructor
|
|
|
271
278
|
def _scan_expansion_for_file(input, filepath, &block)
|
|
272
279
|
# Expand filepath under inspection to ensure proper match
|
|
273
280
|
extraction_filepath = File.expand_path( filepath )
|
|
274
|
-
# Preprocessor directive blocks generally take the form of '# <digits> <text> [optional digits]'
|
|
275
|
-
|
|
281
|
+
# Preprocessor directive blocks generally take the form of '# <digits> <text> [optional digits]'.
|
|
282
|
+
# Leading whitespace is tolerated (`^\s*`, not just `^`): GCC's -fdirectives-only output
|
|
283
|
+
# replaces a top-level #include with a line marker that inherits that #include's own
|
|
284
|
+
# original indentation (GH #1268) -- an indented `#include "x.h"` produces an indented
|
|
285
|
+
# ` # 1 "x.h" 1`, not the flush-left marker every OTHER marker GCC generates uses.
|
|
286
|
+
# Failing to recognize such a marker here leaves `extract` stuck at whatever it already
|
|
287
|
+
# was instead of correctly toggling off, leaking the ignored file's content into output.
|
|
288
|
+
directive = /^\s*# \d+ \"/
|
|
276
289
|
# Line markers have the specific form of '# <digits> "path/filename.ext" [optional digits]' (see above)
|
|
277
|
-
line_marker =
|
|
290
|
+
line_marker = /^\s*#\s(\d+)\s\"(.+)\"/
|
|
278
291
|
# Boolean to ping pong between line-by-line extract/ignore
|
|
279
292
|
extract = false
|
|
280
293
|
|
data/lib/version.rb
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
|
|
28
28
|
:report_generator:
|
|
29
29
|
:verbosity: Warning # Default verbosity
|
|
30
|
-
:collection_paths_source: [] # Explicitly defined as default empty array to simplify option validation code
|
|
31
30
|
:custom_args: [] # Explicitly defined as default empty array to simplify option validation code
|
|
32
31
|
:gcov_exclude: [] # Explicitly defined as default empty array to simplify option validation code
|
|
33
32
|
...
|
|
@@ -169,6 +169,13 @@ class ConsoleReportinator < GcovReportinator
|
|
|
169
169
|
section = section.reject { |line| line.include?( File.basename( source,'.*') ) }
|
|
170
170
|
report = section.map { |line| report_name + ' | ' + line }.join('')
|
|
171
171
|
@loginator.log( report )
|
|
172
|
+
else
|
|
173
|
+
# A Partial whose remapped name still doesn't match any File header in gcov's
|
|
174
|
+
# output -- without this, a Partial's unparseable coverage silently produces no
|
|
175
|
+
# report and no log at all, unlike the equivalent non-Partial case just below.
|
|
176
|
+
@loginator.lazy( Verbosity::COMPLAIN ) do
|
|
177
|
+
"Found no coverage results for #{test}::#{File.basename(source)}"
|
|
178
|
+
end
|
|
172
179
|
end
|
|
173
180
|
|
|
174
181
|
# Otherwise, found no coverage results
|