From 854247d2658f9f8a637bc73a4fa99c50f6832084 Mon Sep 17 00:00:00 2001
From: Raphael Defosseux <raphael.defosseux@eurecom.fr>
Date: Thu, 21 Jun 2018 13:46:40 +0200
Subject: [PATCH] CI: Adding Static Code Analysis stage   -- new stage in
 parallel on a VM   -- detailed reporting of CPPCHECK   -- Option to keep vm
 alive after build (not used yet on jenkins pipeline)

Signed-off-by: Raphael Defosseux <raphael.defosseux@eurecom.fr>
---
 ci-scripts/Jenkinsfile-gitlab    | 11 +++-
 ci-scripts/buildOnVM.sh          | 94 +++++++++++++++++++++++++-------
 ci-scripts/reportBuildLocally.sh | 75 +++++++++++++++++++++++++
 3 files changed, 158 insertions(+), 22 deletions(-)

diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 2021e8347f..7e82261ab8 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -8,7 +8,7 @@ pipeline {
         disableConcurrentBuilds()
         timestamps()
         gitLabConnection('OAI GitLab')
-        gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim"])
+        gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Analysis with cppcheck"])
     }
 
     stages {
@@ -49,6 +49,13 @@ pipeline {
 
         stage ("Variant Builds") {
             parallel {
+                stage ("Analysis with cppcheck") {
+                    steps {
+                        gitlabCommitStatus(name: "Analysis with cppcheck") {
+                            sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck"
+                        }
+                    }
+                }
                 stage ("Build eNb-USRP") {
                     steps {
                         gitlabCommitStatus(name: "Build eNb-USRP") {
@@ -75,7 +82,7 @@ pipeline {
                 always {
                     script {
                         dir ('archives') {
-                            sh "zip -r vm_build_logs.zip basic_sim enb_usrp"
+                            sh "zip -r vm_build_logs.zip basic_sim enb_usrp cppcheck"
                         }
                         if(fileExists('archives/vm_build_logs.zip')) {
                             archiveArtifacts artifacts: 'archives/vm_build_logs.zip'
diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh
index d34fb9a6c4..1ea5eaf50e 100755
--- a/ci-scripts/buildOnVM.sh
+++ b/ci-scripts/buildOnVM.sh
@@ -16,12 +16,16 @@ function usage {
     echo "Options:"
     echo "--------"
     echo "    --workspace #### OR -ws ####"
-    echo "    Specify the workspace"
+    echo "    Specify the workspace."
     echo ""
     echo "    --variant enb-usrp   OR -v1"
     echo "    --variant basic-sim  OR -v2"
     echo "    --variant phy-sim    OR -v3"
-    echo "    Specify the variant to build"
+    echo "    --variant cppcheck   OR -v4"
+    echo "    Specify the variant to build."
+    echo ""
+    echo "    --keep-vm-alive OR -k"
+    echo "    Keep the VM alive after the build."
     echo ""
     echo "    --help OR -h"
     echo "    Print this help message."
@@ -35,10 +39,11 @@ function variant_usage {
     echo "    --variant enb-usrp   OR -v1"
     echo "    --variant basic-sim  OR -v2"
     echo "    --variant phy-sim    OR -v3"
+    echo "    --variant cppcheck   OR -v4"
     echo ""
 }
 
-if [ $# -ne 2 ] && [ $# -ne 1 ] && [ $# -ne 4 ] && [ $# -ne 3 ]
+if [ $# -lt 1 ] || [ $# -gt 5 ]
 then
     echo "Syntax Error: not the correct number of arguments"
     echo ""
@@ -52,6 +57,7 @@ LOG_PATTERN=.Rel14.txt
 NB_PATTERN_FILES=4
 BUILD_OPTIONS="--eNB -w USRP"
 BUILD_EXTRA_OPTIONS="--cflags_processor \"-mssse3 -msse4.1 -mavx2\""
+KEEP_VM_ALIVE=0
 
 while [[ $# -gt 0 ]]
 do
@@ -68,6 +74,10 @@ case $key in
     shift
     shift
     ;;
+    -k|--keep-vm-alive)
+    KEEP_VM_ALIVE=1
+    shift
+    ;;
     -v1)
     VM_NAME=ci-enb-usrp
     ARCHIVES_LOC=enb_usrp
@@ -95,6 +105,15 @@ case $key in
     BUILD_EXTRA_OPTIONS="--cflags_processor \"-mssse3 -msse4.1 -mavx2\""
     shift
     ;;
+    -v4)
+    VM_NAME=ci-cppcheck
+    ARCHIVES_LOC=cppcheck
+    LOG_PATTERN=cppcheck.xml
+    NB_PATTERN_FILES=1
+    BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2"
+    BUILD_EXTRA_OPTIONS=""
+    shift
+    ;;
     --variant)
     variant="$2"
     case $variant in
@@ -122,6 +141,14 @@ case $key in
         BUILD_OPTIONS="--phy_simulators"
         BUILD_EXTRA_OPTIONS="--cflags_processor \"-mssse3 -msse4.1 -mavx2\""
         ;;
+        cppcheck)
+        VM_NAME=ci-cppcheck
+        ARCHIVES_LOC=cppcheck
+        LOG_PATTERN=cppcheck.xml
+        NB_PATTERN_FILES=1
+        BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2"
+        BUILD_EXTRA_OPTIONS=""
+        ;;
         *)
         echo ""
         echo "Syntax Error: Invalid Variant option -> $variant"
@@ -182,20 +209,34 @@ echo "############################################################"
 echo "Running install and build script on VM ($VM_NAME)"
 echo "############################################################"
 echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
-echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS
-echo "sudo apt-get --yes install zip subversion libboost-dev > zip-install.txt 2>&1" >> $VM_CMDS
+if [ "$VM_NAME" == "ci-cppcheck" ]
+then
+    echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS
+    echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
+    echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
+else
+    echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS
+    echo "sudo apt-get --yes install zip subversion libboost-dev > zip-install.txt 2>&1" >> $VM_CMDS
+fi
 echo "mkdir tmp" >> $VM_CMDS
 echo "cd tmp" >> $VM_CMDS
 echo "echo \"unzip -qq ../localZip.zip\"" >> $VM_CMDS
 echo "unzip -qq ../localZip.zip" >> $VM_CMDS
-echo "echo \"source oaienv\"" >> $VM_CMDS
-echo "source oaienv" >> $VM_CMDS
-echo "cd cmake_targets/" >> $VM_CMDS
-echo "mkdir log" >> $VM_CMDS
-echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS
-echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
-echo "./build_oai -I $BUILD_OPTIONS $BUILD_EXTRA_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
-
+if [ "$VM_NAME" == "ci-cppcheck" ]
+then
+    echo "mkdir cmake_targets/log" >> $VM_CMDS
+    echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
+    echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS
+    echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS
+else
+    echo "echo \"source oaienv\"" >> $VM_CMDS
+    echo "source oaienv" >> $VM_CMDS
+    echo "cd cmake_targets/" >> $VM_CMDS
+    echo "mkdir log" >> $VM_CMDS
+    echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS
+    echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
+    echo "./build_oai -I $BUILD_OPTIONS $BUILD_EXTRA_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
+fi
 ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
 
 echo "############################################################"
@@ -212,19 +253,26 @@ then
 fi
 
 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC
+if [ "$VM_NAME" == "ci-cppcheck" ]
+then
+    scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC
+fi
 
-echo "############################################################"
-echo "Destroying VM"
-echo "############################################################"
-uvt-kvm destroy $VM_NAME
-ssh-keygen -R $VM_IP_ADDR
+if [ $KEEP_VM_ALIVE -eq 0 ]
+then
+    echo "############################################################"
+    echo "Destroying VM"
+    echo "############################################################"
+    uvt-kvm destroy $VM_NAME
+    ssh-keygen -R $VM_IP_ADDR
+fi
 rm -f $VM_CMDS
 
 echo "############################################################"
 echo "Checking build status" 
 echo "############################################################"
 
-LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
+LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml`
 STATUS=0
 NB_FOUND_FILES=0
 
@@ -241,7 +289,13 @@ do
         then
             PASS_PATTERN="lte-"
         fi
-        LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
+        if [ "$LOG_PATTERN" == "cppcheck.xml" ]
+        then
+            PASS_PATTERN="results version"
+            LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE`
+        else
+            LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
+        fi
         if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi
         NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
     fi
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index bfa5b258c2..5194b81d4f 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -175,6 +175,69 @@ function summary_table_footer {
     echo "   </table>" >> ./build_results.html
 }
 
+function sca_summary_table_header {
+    echo "   <h3>$1</h3>" >> ./build_results.html
+    echo "   <table border = "1">" >> ./build_results.html
+    echo "      <tr>" >> ./build_results.html
+    echo "        <th>Error Type</th>" >> ./build_results.html
+    echo "        <th>Nb Errors</th>" >> ./build_results.html
+    echo "        <th>Nb Warnings</th>" >> ./build_results.html
+    echo "      </tr>" >> ./build_results.html
+    echo "0" > ccp_error_cnt.txt
+}
+
+function sca_summary_table_row {
+    echo "      <tr>" >> ./build_results.html
+    echo "        <td>$2</td>" >> ./build_results.html
+    if [ -f $1 ]
+    then
+        NB_ERRORS=`egrep "severity=\"error\"" $1 | egrep -c "id=\"$3\""`
+        echo "        <td>$NB_ERRORS</td>" >> ./build_results.html
+        echo "        <td>N/A</td>" >> ./build_results.html
+        if [ -f ccp_error_cnt.txt ]
+        then
+            TOTAL_ERRORS=`cat ccp_error_cnt.txt`
+            TOTAL_ERRORS=$((TOTAL_ERRORS + NB_ERRORS))
+            echo $TOTAL_ERRORS > ccp_error_cnt.txt
+        fi
+    else
+        echo "        <td>Unknown</td>" >> ./build_results.html
+        echo "        <td>Unknown</td>" >> ./build_results.html
+    fi
+    echo "      </tr>" >> ./build_results.html
+}
+
+function sca_summary_table_footer {
+    echo "      <tr>" >> ./build_results.html
+    if [ -f $1 ]
+    then
+        NB_ERRORS=`egrep -c "severity=\"error\"" $1`
+        if [ -f ccp_error_cnt.txt ]
+        then
+            echo "        <td>Others</td>" >> ./build_results.html
+            TOTAL_ERRORS=`cat ccp_error_cnt.txt`
+            TOTAL_ERRORS=$((NB_ERRORS - TOTAL_ERRORS))
+            echo "        <td>$TOTAL_ERRORS</td>" >> ./build_results.html
+            echo "        <td>N/A</td>" >> ./build_results.html
+            echo "      </tr>" >> ./build_results.html
+            echo "      <tr>" >> ./build_results.html
+            rm -f ccp_error_cnt.txt
+        fi
+        echo "        <th>Total</th>" >> ./build_results.html
+        echo "        <th>$NB_ERRORS</th>" >> ./build_results.html
+        NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
+        echo "        <th>$NB_WARNINGS</th>" >> ./build_results.html
+    else
+        echo "        <th>Total</th>" >> ./build_results.html
+        echo "        <th>Unknown</th>" >> ./build_results.html
+        echo "        <th>Unknown</th>" >> ./build_results.html
+    fi
+    echo "      </tr>" >> ./build_results.html
+    echo "   </table>" >> ./build_results.html
+    echo "   <p>Full details in zipped artifact (cppcheck/cppcheck.xml) </p>" >> ./build_results.html
+    echo "   <p>Graphical Interface tool : <code>cppcheck-gui -l cppcheck/cppcheck.xml</code> </p>" >> ./build_results.html
+}
+
 jb_checker=0
 mr_checker=0
 pu_checker=0
@@ -396,6 +459,18 @@ then
     echo "   </table>" >> ./build_results.html
 fi
 
+sca_summary_table_header "OAI Static Code Analysis with CPPCHECK"
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access  out of bounds" arrayIndexOutOfBounds
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds
+sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
+sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
+
 summary_table_header "OAI Build eNB -- USRP option"
 summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html
 summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html
-- 
GitLab