blob: d69a88bc9950409ab5bba04f5bfcce58603f5558 [file] [log] [blame]
E. Scott Daniels4e4fb502020-03-24 12:28:06 -04001#!/usr/bin/env bash
2# vim: ts=4 sw=4 noet :
3
4#==================================================================================
5# Copyright (c) 2020 Nokia
6# Copyright (c) 2020 AT&T Intellectual Property.
7#
8# Licensed under the Apache License, Version 2.0 (the "License");
9# you may not use this file except in compliance with the License.
10# You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an "AS IS" BASIS,
16# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17# See the License for the specific language governing permissions and
18# limitations under the License.
19#==================================================================================
20
21#
22# Parse the .gcov file and discount any unexecuted lines which are in if()
23# blocks which are testing the result of alloc/malloc calls, or testing for
24# nil pointers. The feeling is that these might not be possible to drive
25# and shoudn't contribute to coverage deficiencies.
26#
27# In verbose mode, the .gcov file is written to stdout and any unexecuted
28# line which is discounted is marked with ===== replacing the ##### marking
29# that gcov wrote.
30#
31# The return value is 0 for pass; non-zero for fail.
32#
33function discount_ck {
34 typeset f="$1"
35
36 mct=80 # force minimum coverage threshold for passing
37
38 if [[ ! -f $f ]]
39 then
40 if [[ -f ${f##*/} ]]
41 then
42 f=${f##*/}
43 else
44 echo "cant find: $f"
45 return
46 fi
47 fi
48
49 awk -v module_cov_target=$mct \
50 -v cfail=${cfail:-WARN} \
51 -v show_all=$show_all \
52 -v full_name="${1}" \
53 -v module="${f%.*}" \
54 -v chatty=$chatty \
55 -v replace_flags=$replace_flags \
56 '
57 function spit_line( ) {
58 if( chatty ) {
59 printf( "%s\n", $0 )
60 }
61 }
62
63 /-:/ { # skip unexecutable lines
64 spit_line()
65 seq++ # allow blank lines in a sequence group
66 next
67 }
68
69 {
70 nexec++ # number of executable lines
71 }
72
73 /#####:/ {
74 unexec++;
75 if( $2+0 != seq+1 ) {
76 prev_malloc = 0
77 prev_if = 0
78 seq = 0
79 spit_line()
80 next
81 }
82
83 if( prev_if && prev_malloc ) {
84 if( prev_malloc ) {
85 #printf( "allow discount: %s\n", $0 )
86 if( replace_flags ) {
87 gsub( "#####", " 1", $0 )
88 //gsub( "#####", "=====", $0 )
89 }
90 discount++;
91 }
92 }
93
94 seq++;;
95 spit_line()
96 next;
97 }
98
99 /if[(].*alloc.*{/ { # if( (x = malloc( ... )) != NULL ) or if( (p = sym_alloc(...)) != NULL )
100 seq = $2+0
101 prev_malloc = 1
102 prev_if = 1
103 spit_line()
104 next
105 }
106
107 /if[(].* == NULL/ { # a nil check likely not easily forced if it wasnt driven
108 prev_malloc = 1
109 prev_if = 1
110 spit_line()
111 seq = $2+0
112 next
113 }
114
115 /if[(]/ {
116 if( seq+1 == $2+0 && prev_malloc ) { // malloc on previous line
117 prev_if = 1
118 } else {
119 prev_malloc = 0
120 prev_if = 0
121 }
122 spit_line()
123 next
124 }
125
126 /alloc[(]/ {
127 seq = $2+0
128 prev_malloc = 1
129 spit_line()
130 next
131 }
132
133 {
134 spit_line()
135 }
136
137 END {
138 net = unexec - discount
139 orig_cov = ((nexec-unexec)/nexec)*100 # original coverage
140 adj_cov = ((nexec-net)/nexec)*100 # coverage after discount
141 pass_fail = adj_cov < module_cov_target ? cfail : "PASS"
142 rc = adj_cov < module_cov_target ? 1 : 0
143 if( pass_fail == cfail || show_all ) {
144 if( chatty ) {
145 printf( "[%s] %s executable=%d unexecuted=%d discounted=%d net_unex=%d cov=%d%% ==> %d%% target=%d%%\n",
146 pass_fail, full_name ? full_name : module, nexec, unexec, discount, net, orig_cov, adj_cov, module_cov_target )
147 } else {
148 printf( "[%s] %d%% (%d%%) %s\n", pass_fail, adj_cov, orig_cov, full_name ? full_name : module )
149 }
150 }
151
152 exit( rc )
153 }
154 ' $f
155}
156
157# ----------------------------------------------------------------------
158show_all=1 # turn off to hide passing modules (-q)
159chatty=0 # -v turns on to provide more info when we do speak
160
161while [[ $1 == "-"* ]]
162do
163 case $1 in
164 -q) show_all=0;;
165 -v) chatty=1;;
166
167 *) echo "unrecognised option: $1"
168 echo "usage: $0 [-q] gcov-file-list"
169 exit 1
170 ;;
171 esac
172 shift
173done
174
175
176while [[ -n $1 ]]
177do
178 discount_ck $1
179 shift
180done