Merge "Tools: Improve Stability."
[vswitchperf.git] / check
1 #!/bin/bash
2
3 # Copyright 2017 Intel Corporation.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #   http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # VSPERF code checker
18
19 PYLINT="pylint"
20 PYLINT_RC='pylintrc'
21 PYLINT_RATING_GATE="10"
22 PYLINT_RATING_MIN=$PYLINT_RATING_GATE
23 FILE_REGEX="(^vsperf|\.py)$"
24 FILE_LIST="/tmp/vsperf_check_list.txt"
25 BC=`which bc`
26
27 # print usage if requested
28 function usage() {
29     cat <<EOM
30 Usage: $0 [TARGET]...
31
32 Performs code check for defined TARGETs. Target can be file or directory.
33 In case that directory is specified, then it will be searched recursively
34 for all python files.
35 If TARGET is not specified, then all python files from current VSPERF
36 repository will be checked.
37 Files listed in EXCLUDE_MODULES defined in conf/00_common.conf will be skipped.
38 File will pass check if its pylint rating is greater or equal to $PYLINT_RATING_GATE.
39 Otherwise gained pylint rating will be displayed.
40
41
42     -h, --help                  Script usage
43     -b, --black                 Suppress colours. Output will be black&white.
44     -m, --modified              Script will check python files, which have
45                                 been modified within current repository.
46
47 Examples:
48     ./check
49
50     Check all python files in current VSPERF repository except EXCLUDE_MODULES
51
52     ./check vsperf
53
54     Check just one file.
55
56     ./check -m
57
58     Check all modified files in current VSPERF repository
59
60     ./check vnfs/qemu core tools/pkt_gen
61
62     Check all python files in given directories
63
64 EOM
65 }
66
67 # compare pylint result with predefined gate
68 function rating_is_ok() {
69     # bc is not part of basic Centos installation
70     # so let us check if it is available
71     if [ "x$BC" == "x" ] ; then
72         # no bc, so do integer comparison only
73         int_rating=`echo $1 | sed -e 's/\..*$//'`
74         int_rating_min=`echo $PYLINT_RATING_MIN | sed -e 's/\..*$//'`
75         [ $int_rating -lt $int_rating_min ] && PYLINT_RATING_MIN=$int_rating
76         if [ $int_rating -lt $PYLINT_RATING_GATE ] ; then
77             return 1
78         else
79             return 0
80         fi
81     else
82         if (( $(echo "$1<$PYLINT_RATING_MIN" | bc -l) )) ; then
83             PYLINT_RATING_MIN=$1
84         fi
85         if (( $(echo "$1<$PYLINT_RATING_GATE" | bc -l) )) ; then
86             return 1
87         else
88             return 0
89         fi
90     fi
91 }
92
93 ##### MAIN #####
94 # check if help is requested
95 if [ "x$1" == "x-h" -o "x$1" == "x--help" ] ; then
96     usage
97     exit 0
98 fi
99
100 # set colours
101 if [ "x$1" == "x-b" -o "x$1" == "x--black" ] ; then
102     shift
103     RED=""
104     GREEN=""
105     BLACK=""
106 else
107     RED="\e[31m"
108     GREEN="\e[32m"
109     BLACK="\e[0m"
110 fi
111
112
113 # check if pylint is available
114 if ! which $PYLINT &>/dev/null ; then
115     echo "$PYLINT is not available, thus check can't be executed"
116     exit 1
117 fi
118
119 # check if we were run within vsperf directory
120 if [ ! -x ./vsperf 2> /dev/null ] ; then
121     echo "`basename $0` must be run from vsperf root directory"
122     exit 2
123 fi
124
125 # get list of excluded modules
126 EXCLUDED_MODULES=`grep "^ *EXCLUDE_MODULES" conf/00_common.conf | tr '"' "'"`
127
128 # get list of files to be checked
129 rm $FILE_LIST &> /dev/null
130 if [ "x$1" == "x-m" -o "x$1" == "x--modified" ] ; then
131     # check of modified files requested
132     git status --porcelain | cut -b4- | egrep -i "${FILE_REGEX}" | sort > $FILE_LIST
133 elif [ "x$*" == "x" ] ; then
134     # list is empty, check all python files
135     git ls-tree --name-only -r HEAD | egrep -i "${FILE_REGEX}" | sort > $FILE_LIST
136 else
137     for item in $* ; do
138         if [ -d $item ] ; then
139             git ls-tree --name-only -r HEAD $item | egrep -i "${FILE_REGEX}" | sort >> $FILE_LIST
140         elif [ -f $item ] ; then
141             echo $item >> $FILE_LIST
142         else
143             echo "$item doesn't exist, thus check was aborted"
144             exit 3
145         fi
146     done
147 fi
148
149 # check if there is anything to check
150 echo "Execution of pylint checks:"
151 if [ -s $FILE_LIST ] ; then
152     for pyfile in `cat $FILE_LIST | sort` ; do
153         # get base name
154         pyfile_basename="'"`basename $pyfile .py`"'"
155         # and check if it should be excluded or not
156         if ( echo $EXCLUDED_MODULES | grep -w $pyfile_basename > /dev/null ) ; then
157             printf "    %-70s %-6s\n" $pyfile "EXCLUDED"
158             continue
159         fi
160         # run pylint and extract final rating
161         output=`$PYLINT --rcfile $PYLINT_RC $pyfile 2>/dev/null`
162         rating=`echo -e $output | tail -n3 | grep rated | sed -e 's/^.*rated at \(-\?[0-9.]*\).*$/\1/'`
163         # evaluate and display aquired rating
164         if [ "x$rating" == "x" ] ; then
165             # rating is not available for files without python statements
166             printf "    %-70s %-6s\n" $pyfile "NA"
167         elif rating_is_ok $rating ; then
168             printf "    %-70s ${GREEN}%-6s${BLACK}\n" $pyfile "OK"
169         else
170             echo -e "$output" | awk '/^\*+ Module|^[A-Z]\:/'
171             printf "    %-70s ${RED}%-6s${BLACK}\n" $pyfile $rating
172         fi
173     done
174 else
175     echo "Nothing to check."
176     exit 4
177 fi
178
179 # clean up
180 rm $FILE_LIST &> /dev/null
181
182 if [ "$PYLINT_RATING_MIN" != "$PYLINT_RATING_GATE" ] ; then
183     echo -e "Pylint check has failed. All files must have score ${PYLINT_RATING_GATE}.\n"
184     exit 1
185 else
186     exit 0
187 fi
188 ##### MAIN end #####