blob: 23f238adf6e0ae45f6f489a3b7a20d2d0e4cc8d0 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/bash
2
3# Build performance regression test script
4#
5# Copyright 2011 Intel Corporation
Patrick Williamsc124f4f2015-09-15 14:41:29 -05006#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-or-later
Patrick Williamsc124f4f2015-09-15 14:41:29 -05008#
9# DESCRIPTION
10# This script is intended to be used in conjunction with "git bisect run"
11# in order to find regressions in build time, however it can also be used
12# independently. It cleans out the build output directories, runs a
13# specified worker script (an example is test_build_time_worker.sh) under
14# TIME(1), logs the results to TEST_LOGDIR (default /tmp) and returns a
15# value telling "git bisect run" whether the build time is good (under
16# the specified threshold) or bad (over it). There is also a tolerance
17# option but it is not particularly useful as it only subtracts the
18# tolerance from the given threshold and uses it as the actual threshold.
19#
20# It is also capable of taking a file listing git revision hashes to be
21# test-applied to the repository in order to get past build failures that
22# would otherwise cause certain revisions to have to be skipped; if a
23# revision does not apply cleanly then the script assumes it does not
24# need to be applied and ignores it.
25#
26# Please see the help output (syntax below) for some important setup
27# instructions.
28#
29# AUTHORS
30# Paul Eggleton <paul.eggleton@linux.intel.com>
31
32
33syntax() {
34 echo "syntax: $0 <script> <time> <tolerance> [patchrevlist]"
35 echo ""
36 echo " script - worker script file (if in current dir, prefix with ./)"
37 echo " time - time threshold (in seconds, suffix m for minutes)"
38 echo " tolerance - tolerance (in seconds, suffix m for minutes or % for"
39 echo " percentage, can be 0)"
40 echo " patchrevlist - optional file listing revisions to apply as patches on top"
41 echo ""
42 echo "You must set TEST_BUILDDIR to point to a previously created build directory,"
43 echo "however please note that this script will wipe out the TMPDIR defined in"
44 echo "TEST_BUILDDIR/conf/local.conf as part of its initial setup (as well as your"
45 echo "~/.ccache)"
46 echo ""
47 echo "To get rid of the sudo prompt, please add the following line to /etc/sudoers"
48 echo "(use 'visudo' to edit this; also it is assumed that the user you are running"
49 echo "as is a member of the 'wheel' group):"
50 echo ""
51 echo "%wheel ALL=(ALL) NOPASSWD: /sbin/sysctl -w vm.drop_caches=[1-3]"
52 echo ""
53 echo "Note: it is recommended that you disable crond and any other process that"
54 echo "may cause significant CPU or I/O usage during build performance tests."
55}
56
57# Note - we exit with 250 here because that will tell git bisect run that
58# something bad happened and stop
59if [ "$1" = "" ] ; then
60 syntax
61 exit 250
62fi
63
64if [ "$2" = "" ] ; then
65 syntax
66 exit 250
67fi
68
69if [ "$3" = "" ] ; then
70 syntax
71 exit 250
72fi
73
74if ! [[ "$2" =~ ^[0-9][0-9m.]*$ ]] ; then
75 echo "'$2' is not a valid number for threshold"
76 exit 250
77fi
78
79if ! [[ "$3" =~ ^[0-9][0-9m.%]*$ ]] ; then
80 echo "'$3' is not a valid number for tolerance"
81 exit 250
82fi
83
84if [ "$TEST_BUILDDIR" = "" ] ; then
85 echo "Please set TEST_BUILDDIR to a previously created build directory"
86 exit 250
87fi
88
89if [ ! -d "$TEST_BUILDDIR" ] ; then
90 echo "TEST_BUILDDIR $TEST_BUILDDIR not found"
91 exit 250
92fi
93
94git diff --quiet
95if [ $? != 0 ] ; then
96 echo "Working tree is dirty, cannot proceed"
97 exit 251
98fi
99
100if [ "$BB_ENV_EXTRAWHITE" != "" ] ; then
101 echo "WARNING: you are running after sourcing the build environment script, this is not recommended"
102fi
103
104runscript=$1
105timethreshold=$2
106tolerance=$3
107
108if [ "$4" != "" ] ; then
109 patchrevlist=`cat $4`
110else
111 patchrevlist=""
112fi
113
114if [[ timethreshold == *m* ]] ; then
115 timethreshold=`echo $timethreshold | sed s/m/*60/ | bc`
116fi
117
118if [[ $tolerance == *m* ]] ; then
119 tolerance=`echo $tolerance | sed s/m/*60/ | bc`
120elif [[ $tolerance == *%* ]] ; then
121 tolerance=`echo $tolerance | sed s/%//`
122 tolerance=`echo "scale = 2; (($tolerance * $timethreshold) / 100)" | bc`
123fi
124
125tmpdir=`grep "^TMPDIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/TMPDIR[ \t]*=[ \t\?]*"//' -e 's/"//'`
126if [ "x$tmpdir" = "x" ]; then
127 echo "Unable to determine TMPDIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
128 exit 250
129fi
130sstatedir=`grep "^SSTATE_DIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/SSTATE_DIR[ \t\?]*=[ \t]*"//' -e 's/"//'`
131if [ "x$sstatedir" = "x" ]; then
132 echo "Unable to determine SSTATE_DIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
133 exit 250
134fi
135
136if [ `expr length $tmpdir` -lt 4 ] ; then
137 echo "TMPDIR $tmpdir is less than 4 characters, bailing out"
138 exit 250
139fi
140
141if [ `expr length $sstatedir` -lt 4 ] ; then
142 echo "SSTATE_DIR $sstatedir is less than 4 characters, bailing out"
143 exit 250
144fi
145
146echo -n "About to wipe out TMPDIR $tmpdir, press Ctrl+C to break out... "
147for i in 9 8 7 6 5 4 3 2 1
148do
149 echo -ne "\x08$i"
150 sleep 1
151done
152echo
153
154pushd . > /dev/null
155
156rm -f pseudodone
157echo "Removing TMPDIR $tmpdir..."
158rm -rf $tmpdir
159echo "Removing TMPDIR $tmpdir-*libc..."
160rm -rf $tmpdir-*libc
161echo "Removing SSTATE_DIR $sstatedir..."
162rm -rf $sstatedir
163echo "Removing ~/.ccache..."
164rm -rf ~/.ccache
165
166echo "Syncing..."
167sync
168sync
169echo "Dropping VM cache..."
170#echo 3 > /proc/sys/vm/drop_caches
171sudo /sbin/sysctl -w vm.drop_caches=3 > /dev/null
172
173if [ "$TEST_LOGDIR" = "" ] ; then
174 logdir="/tmp"
175else
176 logdir="$TEST_LOGDIR"
177fi
178rev=`git rev-parse HEAD`
179logfile="$logdir/timelog_$rev.log"
180echo -n > $logfile
181
182gitroot=`git rev-parse --show-toplevel`
183cd $gitroot
184for patchrev in $patchrevlist ; do
185 echo "Applying $patchrev"
186 patchfile=`mktemp`
187 git show $patchrev > $patchfile
188 git apply --check $patchfile &> /dev/null
189 if [ $? != 0 ] ; then
190 echo " ... patch does not apply without errors, ignoring"
191 else
192 echo "Applied $patchrev" >> $logfile
193 git apply $patchfile &> /dev/null
194 fi
195 rm $patchfile
196done
197
198sync
199echo "Quiescing for 5s..."
200sleep 5
201
202echo "Running $runscript at $rev..."
203timeoutfile=`mktemp`
204/usr/bin/time -o $timeoutfile -f "%e\nreal\t%E\nuser\t%Us\nsys\t%Ss\nmaxm\t%Mk" $runscript 2>&1 | tee -a $logfile
205exitstatus=$PIPESTATUS
206
207git reset --hard HEAD > /dev/null
208popd > /dev/null
209
210timeresult=`head -n1 $timeoutfile`
211cat $timeoutfile | tee -a $logfile
212rm $timeoutfile
213
214if [ $exitstatus != 0 ] ; then
215 # Build failed, exit with 125 to tell git bisect run to skip this rev
216 echo "*** Build failed (exit code $exitstatus), skipping..." | tee -a $logfile
217 exit 125
218fi
219
220ret=`echo "scale = 2; $timeresult > $timethreshold - $tolerance" | bc`
221echo "Returning $ret" | tee -a $logfile
222exit $ret
223