1# Script to gather perf and perf/watt data for several workloads
2#
3# Setup:
4#
5# - device connected to monsoon with USB passthrough enabled
6# - network enabled (baseline will be measured and subtracted
7#   from results) (network needed for chrome, youtube tests)
8# - the device is rebooted after each test (can be inhibited
9#   with "-r 0")
10#
11# Default behavior is to run each of the known workloads for
12# 30 minutes gathering both performance and power data.
13#
14# The default time can be overridden with the -t option. To
15# change individual test times, a config file can be specifed
16# via -f with times for individual tests. Example file contents:
17#
18#	idleTime=60
19#	recentflingTime=60
20#	chromeTime=60
21#	youtubeTime=0
22#	sysappsTime=60
23#	suntempleTime=5
24#
25# Output goes to the current directory.
26#
27# Examples:
28#
29# - Run all tests for 15 minutes (default is 30): ./pwrtest.sh -t 15 -R MDA20
30#
31# - Use a config file for test times: ./pwrtest.sh -f ./myconfig -R MDA20
32#
33# - Use a init file to setup device tuneables after each restart (this is
34#   a bash script which should include adb commands to set up device):
35#     ./pwrtest.sh -F devtunables
36#
37
38defaultTime=30
39garbageminutes=8
40
41function Usage {
42	echo "Usage: $0 [OPTIONS]"
43	echo "-d device : device type (shamu, bullhead, ...)"
44	echo "-f configFile : config file to override individual test times"
45	echo "-g garbageMinutes : time to skip power measurement at beginning of test"
46	echo "                    default=$garbagetime minutes"
47	echo "-r restart : 0=no reboot between tests, 1=reboot (default)"
48	echo "-t defaultTimeMin : default time to run each test"
49	echo "                    default=$defaultTime minutes"
50	echo "-D cmddir : directory to find defs.sh"
51	echo "-F restartHookFile : file of commands to set device tunables after restart (optional)"
52	echo "-R release : release running on device (MDA20, 2054728, etc)"
53}
54
55restart=1
56hz=5
57shadowgrid2TimeMax=25
58
59CMDDIR=$(dirname $0 2>/dev/null)
60CMDDIR=${CMDDIR:=.}
61
62MONSOON=monsoon.par
63
64while [ $# -gt 0 ]
65do
66	case "$1" in
67	(-D) CMDDIR=$2; shift;;
68	(-r) restart=$2; shift;;
69	(-t) defaultTime=$2; shift;;
70	(-F) restartfile=$2; shift;;
71	(-g) garbageminutes=$2; shift;;
72	(-f)
73		configFile=$2;
74		echo "Reading configs from $configFile..."
75		. ./$configFile
76		shift;;
77	(-R) echo $2 > ./build; shift;;
78	(--) ;;
79	(--help)
80		Usage
81		exit 0;;
82	(*)
83		echo "Unknown option: $1"
84		Usage
85		exit 1;;
86	esac
87	shift
88done
89
90. $CMDDIR/defs.sh --
91
92devdir="/data/local/tmp"
93suntempledir=${CMDDIR}/suntemple
94
95case $DEVICE in
96(shamu|hammerhead)
97	HWUITEST=hwuitest
98	onSwipe="700 1847 700 400 50"
99	;;
100(*)
101	HWUITEST=hwuitest64
102	onSwipe="500 1200 500 550 150"
103	;;
104esac
105
106scripts="defs.sh systemapps.sh recentfling.sh youtube.sh chromefling.sh $HWUITEST"
107
108if ! $MONSOON >/dev/null 2>&1; then
109	echo $MONSOON must be in your PATH >&2
110	exit 1
111fi
112
113function usbpassthru {
114	if [ "$1" = off ]; then
115		state=off
116	else
117		state=on
118	fi
119	echo Setting usb pass-thru to $state
120	monsoon.par --usbpassthrough=$state
121}
122
123function pwrcollect {
124	collectmin=$1
125	collectmin=${collectmin:=60}
126	# samples = hz * 60 * minutes
127	((samples=5*60*collectmin))
128	monsoon.par --timestamp --samples $samples --hz 5
129}
130
131function copy_files {
132	adb shell mkdir -p $devdir
133	for file in $scripts
134	do
135		adb push $CMDDIR/$file $devdir
136	done
137}
138
139function install_suntemple {
140	echo Checking for suntemple installation...
141	#stdest=/storage/sdcard0/obb/com.BrueComputing.SunTemple
142	stdest=/storage/emulated/0/obb/com.BrueComputing.SunTemple
143	dircontents=$(adb ls $stdest 2>/dev/null)
144	if [ "$dircontents" = "" ]; then
145		echo Installing suntemple...
146		adb install $suntempledir/*.apk
147		adb shell mkdir -p $stdest
148		adb push $suntempledir/main*obb $stdest
149	else
150		echo dircontents=$dircontents
151		echo Suntemple already installed.
152	fi
153}
154
155function run_test {
156	testName=$1
157	collectMinutes=$2
158	collectOutput=${testName}-power-raw.out
159	powerOutput=${testName}-power.out
160	echo -----------------------------------------------------
161	echo TEST: $testName
162	echo enabled Cores $(adb shell "cat /sys/devices/system/cpu/online")
163	date
164	echo -----------------------------------------------------
165	usbpassthru off
166	pwrcollect $collectMinutes > $collectOutput 2>/dev/null
167	# take off the first 2min of samples
168	totalSamples=$(cat $collectOutput | wc -l)
169	# we throw away the first "garbageminutes" of the data
170	# since it is volatile
171	((garbage=hz*60*garbageminutes))
172	((remaining=totalSamples-garbage))
173	if [ $remaining -gt 0 ]; then
174		tail -$remaining $collectOutput > $powerOutput
175	else
176		cp $collectOutput $powerOutput
177	fi
178	echo power data for $testName copied to $collectOutput
179	usbpassthru on
180	sleep 10
181	adb devices
182	sleep 10
183}
184
185function start_job {
186	cmdline="$1"
187	echo Running $cmdline
188	(adb shell "cd $devdir && nohup $cmdline > test.out") &
189	sleep 5
190	kill %1 2>/dev/null
191}
192
193function cleanup_job {
194	testName=$1
195	processName=$2
196	processName=${processName:=" sh "}
197	set -- $(adb shell ps | tr "\r" " " | grep "$processName")
198	echo killing PID=$2...
199	adb shell kill $2
200	sleep 1
201	echo copying test output to $testName...
202	adb pull $devdir/test.out
203	mv test.out ${testName}.out
204	if [ $restart -gt 0 ]; then
205		restart_device
206	else
207		doKeyevent HOME
208	fi
209}
210
211function airplane_mode {
212	if [ "$1" = "on" ]; then
213		mode=true
214		setting=1
215	else
216		mode=false
217		setting=0
218	fi
219	adb shell settings put global airplane_mode_on $setting
220	adb shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state $mode
221	echo Set airplane mode to $mode
222}
223
224function restart_device {
225	adb reboot
226	echo Wait 60s for device to restart...
227	sleep 60
228	while ! adb root
229	do
230		echo Waiting for device to come up...
231		sleep 10
232	done
233	echo Wait 30s to complete boot activities...
234	sleep 30
235	echo Restart complete.
236	doTap 897 1075
237	sleep 2
238	doSwipe $onSwipe
239	restartfile=${restartfile:="./restarthook"}
240	if [ -f $restartfile ]; then
241		# hook to change tunables after a restart
242		. $restartfile
243	fi
244}
245
246usbpassthru on
247adb devices 2>/dev/null
248
249airplane_mode off
250if [ $restart -gt 0 ]; then
251	restart_device
252fi
253
254echo Copying $scripts to device $devdir...
255copy_files
256tests=""
257
258# measure background power
259idleTime=${idleTime:=$defaultTime}
260if [ $idleTime -gt 0 ]; then
261	echo Test 1 : measure idle power for $idleTime minutes
262	run_test idle $idleTime
263	airplane_mode on
264	echo Restarting for power baseline in airplane mode...
265	restart_device
266	run_test idle-airplane $idleTime
267	airplane_mode off
268	# the screen blanks after 30 minutes. The first 2 minutes of the test
269	# have already been filtered off. For our power baseline, keep the first
270	# 20 minutes of the results
271	((twentyminutes=hz*20*60))
272	powerOutput="idle-power.out"
273	displayPowerOutput="idle-display-power.out"
274	airplanePowerOutput="idle-airplane-power.out"
275	airplaneDisplayPowerOutput="idle-airplane-display-power.out"
276	totalSamples=$(cat $powerOutput | wc -l)
277	if [ $twentyminutes -lt $totalSamples ]; then
278		head -$twentyminutes $powerOutput > $displayPowerOutput
279		head -$twentyminutes $airplanePowerOutput > $airplaneDisplayPowerOutput
280	else
281		cp $powerOutput $displayPowerOutput
282		cp $airplanePowerOutput $airplaneDisplayPowerOutput
283	fi
284	tests="$tests idle"
285fi
286
287recentflingTime=${recentflingTime:=$defaultTime}
288if [ $recentflingTime -gt 0 ]; then
289	echo $(date) Test 2 : recents fling for $recentflingTime minutes
290	airplane_mode on
291	adb shell "cd $devdir && ./systemapps.sh -A -T -i 1"
292	start_job "./recentfling.sh -N -i 1000 -d $DEVICE"
293	run_test recentfling $recentflingTime
294	cleanup_job recentfling
295	airplane_mode off
296	date
297	tests="$tests recentfling"
298fi
299
300suntempleTime=${suntempleTime:=$defaultTime}
301if [ $suntempleTime -gt 0 ]; then
302	echo $(date) Test 2 : run Sun Temple $suntempleTime minutes
303	airplane_mode on
304	install_suntemple
305	adb shell "am start $suntempleActivity"
306	run_test suntemple $suntempleTime
307	adb pull /sdcard/SunTemple/SunTemple/Saved/Logs/SunTemple.log
308	cleanup_job suntemple BrueComp
309	airplane_mode off
310	mv SunTemple.log suntemple.out
311	# grab the suntemple log
312	date
313	tests="$tests suntemple"
314fi
315
316chromeTime=${chromeTime:=$defaultTime}
317if [ $chromeTime -gt 0 ]; then
318	echo $(date) Test 3 : chrome fling for $chromeTime minutes
319	start_job "./chromefling.sh -i 1000 -d $DEVICE"
320	run_test chrome $chromeTime
321	cleanup_job chrome
322	date
323	tests="$tests chrome"
324fi
325
326shadowgrid2Time=${shadowgrid2Time:=$defaultTime}
327if [ $shadowgrid2Time -gt $shadowgrid2TimeMax ]; then
328	# we cap shadowgrid2 time since the display goes
329	# off after 30 minutes
330	$shadowgrid2Time=$shadowgrid2TimeMax
331fi
332if [ $shadowgrid2Time -gt 0 ]; then
333	airplane_mode on
334	echo $(date) Test 4 : shadowgrid2 for $shadowgrid2Time minutes
335	start_job "./$HWUITEST shadowgrid2 100000"
336	run_test shadowgrid2 $shadowgrid2Time
337	cleanup_job shadowgrid2 $HWUITEST
338	airplane_mode off
339	date
340	tests="$tests shadowgrid2"
341fi
342
343youtubeTime=${youtubeTime:=$defaultTime}
344if [ $youtubeTime -gt 0 ]; then
345	echo $(date) Test 5 : youtube for $youtubeTime minutes
346	start_job "./youtube.sh -i 1000 -d $DEVICE"
347	run_test youtube $youtubeTime
348	cleanup_job youtube
349	date
350	tests="$tests youtube"
351fi
352
353sysappsTime=${sysappsTime:=$defaultTime}
354if [ $sysappsTime -gt 0 ]; then
355	echo $(date) Test 6 : app switching for $sysappsTime minutes
356	start_job "./systemapps.sh -T -i 1000 -d $DEVICE"
357	run_test sysapps $sysappsTime
358	cleanup_job sysapps
359	date
360	tests="$tests sysapps"
361fi
362
363echo Ran tests: $tests
364echo $tests > tests
365
366