Add unit tests and changes related
[ric-plt/xapp-frame-cpp.git] / test / parse_gcov.sh
diff --git a/test/parse_gcov.sh b/test/parse_gcov.sh
new file mode 100755 (executable)
index 0000000..d69a88b
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+# vim: ts=4 sw=4 noet :
+
+#==================================================================================
+#       Copyright (c) 2020 Nokia
+#       Copyright (c) 2020 AT&T Intellectual Property.
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#==================================================================================
+
+#
+#      Parse the .gcov file and discount any unexecuted lines which are in if()
+#      blocks which are testing the result of alloc/malloc calls, or testing for
+#      nil pointers.  The feeling is that these might not be possible to drive
+#      and shoudn't contribute to coverage deficiencies.
+#
+#      In verbose mode, the .gcov file is written to stdout and any unexecuted
+#      line which is discounted is marked with ===== replacing the ##### marking
+#      that gcov wrote.
+#
+#      The return value is 0 for pass; non-zero for fail.
+#
+function discount_ck {
+       typeset f="$1"
+
+       mct=80                                                  # force minimum coverage threshold for passing
+
+       if [[ ! -f $f ]]
+       then
+               if [[ -f ${f##*/} ]]
+               then
+                       f=${f##*/}
+               else
+                       echo "cant find: $f"
+                       return
+               fi
+       fi
+
+       awk -v module_cov_target=$mct \
+               -v cfail=${cfail:-WARN} \
+               -v show_all=$show_all \
+               -v full_name="${1}"  \
+               -v module="${f%.*}"  \
+               -v chatty=$chatty \
+               -v replace_flags=$replace_flags \
+       '
+       function spit_line( ) {
+               if( chatty ) {
+                       printf( "%s\n", $0 )
+               }
+       }
+
+       /-:/ {                                          # skip unexecutable lines
+               spit_line()
+               seq++                                   # allow blank lines in a sequence group
+               next
+       }
+
+       {
+               nexec++                                 # number of executable lines
+       }
+
+       /#####:/ {
+               unexec++;
+               if( $2+0 != seq+1 ) {
+                       prev_malloc = 0
+                       prev_if = 0
+                       seq = 0
+                       spit_line()
+                       next
+               }
+
+               if( prev_if && prev_malloc ) {
+                       if( prev_malloc ) {
+                               #printf( "allow discount: %s\n", $0 )
+                               if( replace_flags ) {
+                                       gsub( "#####", "    1", $0 )
+                                       //gsub( "#####", "=====", $0 )
+                               }
+                               discount++;
+                       }
+               }
+
+               seq++;;
+               spit_line()
+               next;
+       }
+
+       /if[(].*alloc.*{/ {                     # if( (x = malloc( ... )) != NULL ) or if( (p = sym_alloc(...)) != NULL )
+               seq = $2+0
+               prev_malloc = 1
+               prev_if = 1
+               spit_line()
+               next
+       }
+
+       /if[(].* == NULL/ {                             # a nil check likely not easily forced if it wasnt driven
+               prev_malloc = 1
+               prev_if = 1
+               spit_line()
+               seq = $2+0
+               next
+       }
+
+       /if[(]/ {
+               if( seq+1 == $2+0 && prev_malloc ) {            // malloc on previous line
+                       prev_if = 1
+               } else {
+                       prev_malloc = 0
+                       prev_if = 0
+               }
+               spit_line()
+               next
+       }
+
+       /alloc[(]/ {
+               seq = $2+0
+               prev_malloc = 1
+               spit_line()
+               next
+       }
+
+       {
+               spit_line()
+       }
+
+       END {
+               net = unexec - discount
+               orig_cov = ((nexec-unexec)/nexec)*100           # original coverage
+               adj_cov = ((nexec-net)/nexec)*100                       # coverage after discount
+               pass_fail = adj_cov < module_cov_target ? cfail : "PASS"
+               rc = adj_cov < module_cov_target ? 1 : 0
+               if( pass_fail == cfail || show_all ) {
+                       if( chatty ) {
+                               printf( "[%s] %s executable=%d unexecuted=%d discounted=%d net_unex=%d  cov=%d%% ==> %d%%  target=%d%%\n",
+                                       pass_fail, full_name ? full_name : module, nexec, unexec, discount, net, orig_cov, adj_cov, module_cov_target )
+                       } else {
+                               printf( "[%s] %d%% (%d%%) %s\n", pass_fail, adj_cov, orig_cov, full_name ? full_name : module )
+                       }
+               }
+
+               exit( rc )
+       }
+       ' $f
+}
+
+# ----------------------------------------------------------------------
+show_all=1                     # turn off to hide passing modules (-q)
+chatty=0                       # -v turns on to provide more info when we do speak
+
+while [[ $1 == "-"* ]]
+do
+       case $1 in 
+               -q)     show_all=0;;
+               -v)     chatty=1;;
+
+               *)      echo "unrecognised option: $1"
+                       echo "usage: $0 [-q] gcov-file-list"
+                       exit 1
+                       ;;
+       esac
+       shift
+done
+
+
+while [[ -n $1 ]]
+do
+       discount_ck $1
+       shift
+done