3 #==================================================================================
4 # Copyright (c) 2018-2019 AT&T Intellectual Property.
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #==================================================================================
21 # Mnemonic: discount_chk.ksh
22 # Abstract: This checks the gcov output from unit tests to determine
23 # what number of lines of code are highly untestable. Primararily
24 # these are lines in blocks which are executed when systems
25 # calles (e.g. malloc) fail.
27 # Date: 10 December 2019
28 # Author: E. Scott Daniels
29 # -------------------------------------------------------------------------
33 # Parse the .gcov file and discount any unexecuted lines which are in if()
34 # blocks that are testing the result of alloc/malloc calls, or testing for
35 # nil pointers. The feeling is that these might not be possible to drive
36 # and shoudn't contribute to coverage deficiencies.
38 # In verbose mode, the .gcov file is written to stdout and any unexecuted
39 # line which is discounted is marked with ===== replacing the ##### marking
42 # The return value is 0 for pass; non-zero for fail.
43 function discount_gcov {
46 #mct=$( get_mct ${1%.gcov} ) # see if a special coverage target is defined for this
60 awk -v module_cov_target=$mct \
61 -v cfail=${cfail:-WARN} \
62 -v show_all=$show_all \
66 -v replace_flags=$replace_flags \
68 function spit_line( ) {
74 /-:/ { # skip unexecutable lines
76 seq++ # allow blank lines in a sequence group
81 nexec++ # number of executable lines
94 if( prev_if && prev_malloc ) {
96 #printf( "allow discount: %s\n", $0 )
98 if( replace_flags == 1 ) {
99 gsub( "#####", " 1", $0 )
101 gsub( "#####", "=====", $0 )
113 /if[(].*errno ==.*{/ || # if( errno == ... ) assume error check
115 /if[(].*alloc.*{/ { # if( (x = malloc( ... )) != NULL ) or if( (p = sym_alloc(...)) != NULL )
123 /if[(].* == NULL/ { # a nil check likely not easily forced if it wasnt driven
132 if( seq+1 == $2+0 && prev_malloc ) { # malloc on previous line
154 net = unexec - discount
155 orig_cov = ((nexec-unexec)/nexec)*100 # original coverage
156 adj_cov = ((nexec-net)/nexec)*100 # coverage after discount
157 pass_fail = adj_cov < module_cov_target ? cfail : "PASS"
158 rc = adj_cov < module_cov_target ? 1 : 0
159 if( pass_fail == cfail || show_all ) {
161 printf( "[%s] %s executable=%d unexecuted=%d discounted=%d net_unex=%d cov=%d%% ==> %d%% target=%d%%\n",
162 pass_fail, full_name ? full_name : module, nexec, unexec, discount, net, orig_cov, adj_cov, module_cov_target )
164 printf( "[%s] %d%% (%d%%) %s\n", pass_fail, adj_cov, orig_cov, full_name ? full_name : module )
173 # ----------------------------------------------------------------
185 -a) show_all-1;; # only show things not passing
186 -c) module_cov_target=$2;; # coverage target for module
187 -r) replace_flag=$2; shift;; # replace with ==== if 2; no repalce if 0
188 -V) chatty=1;; # show "dcov" output
196 discount_gcov ${ckf%.gcov}.gcov