~jocave/checkbox/hybrid-amd-gpu-mods

« back to all changes in this revision

Viewing changes to checkbox-old/scripts/suspend_test

  • Committer: Zygmunt Krynicki
  • Date: 2013-05-29 07:50:30 UTC
  • mto: This revision was merged to the branch mainline in revision 2153.
  • Revision ID: zygmunt.krynicki@canonical.com-20130529075030-ngwz245hs2u3y6us
checkbox: move current checkbox code into checkbox-old

This patch cleans up the top-level directory of the project into dedicated
sub-project directories. One for checkbox-old (the current checkbox and all the
associated stuff), one for plainbox and another for checkbox-ng.

There are some associated changes, such as updating the 'source' mode of
checkbox provider in plainbox, and fixing paths in various test scripts that we
have.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/bash
 
2
#
 
3
# Script to automate suspend / resume
 
4
#
 
5
# Copyright (C) 2008-2009 Canonical Ltd.
 
6
#
 
7
# Authors:
 
8
#  Michael Frey <michael.frey@canonical.com>
 
9
#  Andy Whitcroft <apw@canonical.com>
 
10
#
 
11
# This program is free software: you can redistribute it and/or modify
 
12
# it under the terms of the GNU General Public License version 2,
 
13
# as published by the Free Software Foundation.
 
14
#
 
15
# This program is distributed in the hope that it will be useful,
 
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
# GNU General Public License for more details.
 
19
#
 
20
# You should have received a copy of the GNU General Public License
 
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
 
 
23
#
 
24
# Script to automate suspend / resume
 
25
#
 
26
# We set a RTC alarm that wakes the system back up and then sleep
 
27
# for  seconds before we go back to sleep.
 
28
#
 
29
# Changelog:
 
30
#
 
31
# V8:
 
32
#  - add a new suspend battery drain test
 
33
#  - track batteries disabling tests which require them automatically
 
34
#  - disable dbus tests when we have no primary user
 
35
#  - include the new power drain test in --full
 
36
#  - handle AC transitions better
 
37
#  - use minutes in messages where appropriate
 
38
#  - report AC transition failures
 
39
#  - only mention AC when we have batteries
 
40
#  - report results at the bottom for easy posting
 
41
#
 
42
# V7:
 
43
#  - add a --dry-run mode to simplify developement
 
44
#  - add a automation mode for checkbox integration
 
45
#  - add a new pm-suspend test
 
46
#  - record and restore timer_delay around the variable time test.
 
47
#
 
48
# V6:
 
49
#  - move an --enable/--disable interface for tests
 
50
#  - add --set to allow setting of approved parameters
 
51
#  - fix up prompting for interactive and non-interactive tests
 
52
#  - supply a sensible default for testing on servers (apw, kirkland)
 
53
#
 
54
# V5:
 
55
#  - send dbus messages as the original user
 
56
#  - stop clearing the dmesg as we go
 
57
#  - stop using trace generally as this affects the wakeups
 
58
#  - do a single dbus test then move to pm-suspend to avoid screensaver
 
59
#  - timeout waiting for a suspend to complete catching failure to go down
 
60
#
 
61
# V4:
 
62
#  - update the help output
 
63
#  - add --comprehensive to do AC related tests
 
64
#  - add --extensive to do a range of time related tests
 
65
#  - add --full to enable all harder tests
 
66
#  - add fallback to pm-suspend for Kbuntu
 
67
#  - collect dmesg output
 
68
#  - remove hwclock update
 
69
#
 
70
# V3:
 
71
#  - fix typo in fallback acpi interface
 
72
#  - when recording the RTC clock do not go direct
 
73
#  - pmi is now deprecated suspend using dbus
 
74
#
 
75
# V2:
 
76
#  - support newer rtc sysfs wakealarm interface
 
77
#  - move to using pmi action suspend
 
78
#  - allow the user to specify the number of iterations
 
79
#  - ensure we are running as root
 
80
#  - report the iterations to the user
 
81
#  - clean up the output and put it in a standard logfile
 
82
#  - add a descriptive warning and allow user cancel
 
83
#  - add tracing enable/disable
 
84
#  - fix logfile location
 
85
#  - add a failure cleanup mode
 
86
#  - make time sleep time and delay time configurable
 
87
#  - ensure the log directory exists
 
88
#  - clock will be fixed automatically on network connect
 
89
#  - default sleep before wakeup to 20s
 
90
#  - do not use dates after we have corrupted the clock
 
91
#  - sort out the copyright information
 
92
#  - we do not have any failure cleanup currently
 
93
#
 
94
# V1:
 
95
#  - add the suspend test scripts
 
96
#
 
97
P="test-suspend"
 
98
 
 
99
LOGDIR='/var/lib/pm-utils'
 
100
LOGFILE="$LOGDIR/stress.log"
 
101
 
 
102
setup_wakeup_timer ()
 
103
{
 
104
        timeout="$1"
 
105
 
 
106
        #
 
107
        # Request wakeup from the RTC or ACPI alarm timers.  Set the timeout
 
108
        # at 'now' + $timeout seconds.
 
109
        #
 
110
        ctl='/sys/class/rtc/rtc0/wakealarm'
 
111
        if [ -f "$ctl" ]; then
 
112
                # Cancel any outstanding timers.
 
113
                echo "0" >"$ctl"
 
114
                # rtcN/wakealarm can use relative time in seconds
 
115
                echo "+$timeout" >"$ctl"
 
116
                return 0
 
117
        fi
 
118
        ctl='/proc/acpi/alarm'
 
119
        if [ -f "$ctl" ]; then
 
120
                echo `date '+%F %H:%M:%S' -d '+ '$timeout' seconds'` >"$ctl"
 
121
                return 0
 
122
        fi
 
123
 
 
124
        echo "no method to awaken machine automatically" 1>&2
 
125
        exit 1
 
126
}
 
127
 
 
128
suspend_system ()
 
129
{
 
130
        if [ "$dry" -eq 1 ]; then
 
131
                echo "DRY-RUN: suspend machine for $timer_sleep"
 
132
                sleep 1
 
133
                return
 
134
        fi
 
135
 
 
136
        setup_wakeup_timer "$timer_sleep"
 
137
 
 
138
        dmesg >"$LOGFILE.dmesg.A"
 
139
 
 
140
        # Send a dbus message to initiate Suspend.
 
141
        if [ "$suspend_dbus" -eq 1 ]; then
 
142
                sudo -u $SUDO_USER dbus-send --session --type=method_call \
 
143
                        --dest=org.freedesktop.PowerManagement \
 
144
                        /org/freedesktop/PowerManagement \
 
145
                        org.freedesktop.PowerManagement.Suspend \
 
146
                        >> "$LOGFILE" || {
 
147
                                ECHO "FAILED: dbus suspend failed"
 
148
                                return
 
149
                        }
 
150
        else
 
151
                pm-suspend >> "$LOGFILE"
 
152
        fi
 
153
 
 
154
        # Wait on the machine coming back up -- pulling the dmesg over.
 
155
        echo "v---" >>"$LOGFILE"
 
156
        retry=30
 
157
        while [ "$retry" -gt 0 ]; do
 
158
                let "retry=$retry-1"
 
159
 
 
160
                # Accumulate the dmesg delta.
 
161
                dmesg >"$LOGFILE.dmesg.B"
 
162
                diff "$LOGFILE.dmesg.A" "$LOGFILE.dmesg.B" | \
 
163
                        grep '^>' >"$LOGFILE.dmesg"
 
164
                mv "$LOGFILE.dmesg.B" "$LOGFILE.dmesg.A"
 
165
 
 
166
                echo "Waiting for suspend to complete $retry to go ..." \
 
167
                                                        >> "$LOGFILE"
 
168
                cat "$LOGFILE.dmesg" >> "$LOGFILE"
 
169
 
 
170
                if [ "`grep -c 'Back to C!' $LOGFILE.dmesg`" -ne 0 ]; then
 
171
                        break;
 
172
                fi
 
173
                sleep 1
 
174
        done
 
175
        echo "^---" >>"$LOGFILE"
 
176
        rm -f "$LOGFILE.dmesg"*
 
177
        if [ "$retry" -eq 0 ]; then
 
178
                ECHO "SUSPEND FAILED, did not go to sleep"
 
179
        fi
 
180
}
 
181
 
 
182
delay_system ()
 
183
{
 
184
        if [ "$dry" -eq 1 ]; then
 
185
                echo "DRY-RUN: stay awake for $timer_delay"
 
186
                sleep 1
 
187
                return
 
188
        fi
 
189
 
 
190
        #
 
191
        # wait for $timer_delay seconds after system resume from S3
 
192
        #
 
193
        ECHO "wait for $timer_delay seconds"
 
194
        sleep $timer_delay
 
195
}
 
196
 
 
197
ECHO ()
 
198
{
 
199
        echo "$@" | tee -a "$LOGFILE"
 
200
}
 
201
 
 
202
run_suspend ()
 
203
{
 
204
        CNT=1
 
205
        TOTAL=$1
 
206
        ECHO "Suspend Test starting on $(date '+%F %H:%M:%S') ($TOTAL cycles)"
 
207
        while [ "$CNT" -le "$TOTAL" ]
 
208
        do
 
209
                ECHO "Suspend iteration $CNT of $TOTAL"
 
210
 
 
211
                suspend_system "$START"
 
212
                delay_system
 
213
 
 
214
                (( CNT++ ))
 
215
        done
 
216
        ECHO "Suspend Test completed"
 
217
}
 
218
 
 
219
enable_trace()
 
220
{
 
221
    echo 1 > '/sys/power/pm_trace'
 
222
}
 
223
 
 
224
disable_trace()
 
225
{
 
226
    echo 0 > '/sys/power/pm_trace'
 
227
}
 
228
 
 
229
# Battery
 
230
battery_count()
 
231
{
 
232
        cat /proc/acpi/battery/*/state 2>/dev/null | \
 
233
        awk '
 
234
                BEGIN                   { total = 0 }
 
235
                /present:.*yes/         { total += 1 }
 
236
                END                     { print total }
 
237
        '
 
238
}
 
239
battery_capacity()
 
240
{
 
241
        cat /proc/acpi/battery/*/state 2>/dev/null | \
 
242
        awk '
 
243
                BEGIN                   { total = 0 }
 
244
                /remaining capacity:/   { total += $3 }
 
245
                END                     { print total }
 
246
        '
 
247
}
 
248
 
 
249
#
 
250
# MAIN
 
251
#
 
252
usage() {
 
253
        cat - 1>&2 <<EOM
 
254
Usage: $P [<options>]
 
255
Options:
 
256
 --sleep <seconds>         - how long the machine wait before waking
 
257
 --delay <seconds>         - default delay between iterations
 
258
 
 
259
 --enable <test>           - enable a specific test
 
260
 --disable <test>          - disable a specific test
 
261
 --set <test>.<var>=<val>  - set a test specific variable
 
262
     dbus                    - perform a suspend via dbus
 
263
     ac                      - perform tests involving removing ac power
 
264
     timed                   - perform a variable timing test
 
265
     repeat                  - perform a longer repeat test
 
266
       .iterations             - the number of iterations in the repeat
 
267
     power                   - perform a battery consumption test
 
268
       .sleep                  - how long to sleep
 
269
 
 
270
 --full                    - run a basic set of tests
 
271
 --server                  - run those test appropriate for a server
 
272
EOM
 
273
}
 
274
 
 
275
# We need TEMP as the `eval set --' would nuke the return value of getopt.
 
276
TEMP=`getopt -o '' -l dry-run,auto,,sleep:,delay:,enable:,disable:,set:,full,desktop,server -n "$P" -- "$@"`
 
277
if [ $? != 0 ] ; then
 
278
        usage
 
279
        exit 1
 
280
fi
 
281
 
 
282
# Note the quotes around `$TEMP': they are essential!
 
283
eval set -- "$TEMP"
 
284
 
 
285
# Options helpers.
 
286
chk_test ()
 
287
{
 
288
        if ! declare -p "test_$1" 2>/dev/null 1>&2; then
 
289
                echo "$P: $1: test unknown" 1>&2
 
290
                exit 1
 
291
        fi
 
292
}
 
293
handle_set ()
 
294
{
 
295
        stmt=`echo "$1" | sed -e 's/\./_/g'`
 
296
 
 
297
        test="${stmt%%_*}"
 
298
        var="${stmt%%=*}"
 
299
 
 
300
        chk_test "$test"
 
301
        if ! declare -p "args_$var" 2>/dev/null 1>&2; then
 
302
                echo "$P: $var: test variable unknown" 1>&2
 
303
                exit 1
 
304
        fi
 
305
        
 
306
        RET="args_$stmt"
 
307
}
 
308
chk_number() {
 
309
        eval "val=\"\$$1\""
 
310
        let num="0+$val"
 
311
        if [ "$val" != "$num" ]; then
 
312
                name=`echo "$1" | sed -e 's/args_//' -e 's/_/./'`
 
313
                echo "$P: $name: $val: non-numeric value" 1>&2
 
314
                exit 1
 
315
        fi
 
316
}
 
317
 
 
318
# Options handling.
 
319
dry=0
 
320
auto=0
 
321
timer_sleep=20
 
322
timer_delay=10
 
323
 
 
324
test_dbus=0
 
325
test_pmsuspend=0
 
326
test_ac=0
 
327
test_timed=0
 
328
test_repeat=0
 
329
args_repeat_iterations=10
 
330
test_power=0
 
331
args_power_sleep=1200
 
332
 
 
333
while :
 
334
do
 
335
        case "$1" in
 
336
        --dry-run)              dry=1; shift 1 ;;
 
337
        --auto)                 auto=1; shift 1 ;;
 
338
        --sleep)                timer_sleep="$2"; shift 2 ;;
 
339
        --delay)                timer_delay="$2"; shift 2 ;;
 
340
        --disable)              chk_test "$2"; declare "test_$1=0"; shift 2 ;;
 
341
        --enable)               chk_test "$2"; declare "test_$2=1"; shift 2 ;;
 
342
        --set)                  handle_set "$2"; declare "$RET"; shift 2 ;;
 
343
        --desktop|--full)       test_dbus=1; test_ac=1; test_timed=1;
 
344
                                test_power=1; shift 1 ;;
 
345
        --server)               test_timed=1; shift 1 ;;
 
346
        --)                     shift; break ;;
 
347
        *)                      echo "$1: ERROR"; exit 1 ;;
 
348
        esac
 
349
done
 
350
 
 
351
chk_number "args_repeat_iterations"
 
352
chk_number "args_power_sleep"
 
353
 
 
354
tests=`set | grep ^test_ | grep -c =1`
 
355
 
 
356
if [ "$#" -gt 1 ]; then
 
357
        usage
 
358
        exit 1
 
359
fi
 
360
if [ "$tests" -eq 0 ]; then
 
361
        usage
 
362
        echo "$P: no tests selected" 1>&2
 
363
        exit 1
 
364
fi
 
365
 
 
366
battery_count=`battery_count`
 
367
 
 
368
report_battery=''
 
369
 
 
370
suspend_dbus=0
 
371
 
 
372
# Check we are running as root as we are going to fiddle with the clock
 
373
# and use the rtc wakeups.
 
374
id=`id -u`
 
375
if [ "$id" -ne 0 ]; then
 
376
        echo "ERROR: must be run as root to perform this test, use sudo:" 1>&2
 
377
        echo "       sudo $0 $@" 1>&2
 
378
        exit 1
 
379
fi
 
380
 
 
381
ac_needed=-1
 
382
ac_is=-1
 
383
ac_becomes=-1
 
384
ac_required()
 
385
{
 
386
        ac_check
 
387
 
 
388
        ac_needed="$1"
 
389
        ac_becomes="$1"
 
390
}
 
391
ac_transitions()
 
392
{
 
393
        ac_check
 
394
 
 
395
        ac_needed="$1"
 
396
        ac_becomes="$2"
 
397
}
 
398
ac_online()
 
399
{
 
400
        cat /proc/acpi/ac_adapter/*/state 2>/dev/null | \
 
401
        awk '
 
402
                BEGIN                   { online = 0; offline = 0 }
 
403
                /on-line/               { online = 1 }
 
404
                /off-line/              { offline = 1 }
 
405
                END                     {
 
406
                                                if (online) {
 
407
                                                        print "1"
 
408
                                                } else if (offline) {
 
409
                                                        print "0"
 
410
                                                } else {
 
411
                                                        print "-1"
 
412
                                                }
 
413
                                        }
 
414
        '
 
415
}
 
416
ac_check()
 
417
{
 
418
        typeset ac_current=`ac_online`
 
419
 
 
420
        if [ "$ac_becomes" -ne -1 -a "$ac_current" -ne -1 -a \
 
421
                        "$ac_current" -ne "$ac_becomes" ]; then
 
422
                ECHO "*** WARNING: AC power not in expected state" \
 
423
                        "($ac_becomes) after test"
 
424
        fi
 
425
        ac_is="$ac_becomes"
 
426
}
 
427
 
 
428
phase=0
 
429
phase_first=1
 
430
phase_interactive=1
 
431
phase()
 
432
{
 
433
        typeset sleep
 
434
 
 
435
        let phase="$phase+1"
 
436
 
 
437
        echo ""
 
438
        echo "*** TEST $phase -- $1"
 
439
        shift 1
 
440
        for line in "$@"
 
441
        do
 
442
                echo "*** $line"
 
443
        done
 
444
        if [ "$battery_count" -ne 0 -a "$ac_needed" -ne "$ac_is" ]; then
 
445
                case "$ac_needed" in
 
446
                0) echo "*** please ensure your AC cord is detached" ;;
 
447
                1) echo "*** please ensure your AC cord is attached" ;;
 
448
                esac
 
449
                ac_is="$ac_needed"
 
450
        fi
 
451
        
 
452
        if [ "$timer_sleep" -gt 60 ]; then
 
453
                let sleep="$timer_sleep / 60"
 
454
                sleep="$sleep minutes"
 
455
        else
 
456
                sleep="$timer_sleep seconds"
 
457
        fi
 
458
        echo "*** machine will suspend for $sleep"
 
459
 
 
460
        if [ "$auto" -eq 1 ]; then
 
461
                :
 
462
 
 
463
        elif [ "$phase_interactive" -eq 1 ]; then
 
464
                echo "*** press return when ready"
 
465
                read x
 
466
 
 
467
        elif [ "$phase_first" -eq 1 ]; then
 
468
                echo "*** NOTE: there will be no further user interaction from this point"
 
469
                echo "*** press return when ready"
 
470
                phase_first=0
 
471
                read x
 
472
        fi
 
473
        echo ""
 
474
}
 
475
 
 
476
[ "$auto" -eq 0 ] && cat - <<EOM
 
477
This script will attempt to suspend and resume your computer a number of times.
 
478
Should the machine fail to resume, first attempt to manually resume it.  If
 
479
that fails power your system off and on which will generate an apport bug
 
480
report automatically.
 
481
 
 
482
Press CTRL-C now to abort testing ...
 
483
EOM
 
484
 
 
485
# Ensure the log directory exists.
 
486
mkdir -p "$LOGDIR"
 
487
 
 
488
phase_interactive=1
 
489
if [ "$test_dbus" -eq 1 -a \
 
490
                \( "$SUDO_USER" = "" -o "$SUDO_USER" = "root" \) ]; then
 
491
        ECHO "*** no primary user (via sudo) dbus tests skipped ..."
 
492
elif [ "$test_dbus" -eq 1 ]; then
 
493
        ac_required 1
 
494
        suspend_dbus=1
 
495
        phase "suspend triggered via dbus message"
 
496
        suspend_system
 
497
        suspend_dbus=0
 
498
fi
 
499
if [ "$test_pmsuspend" -eq 1 ]; then
 
500
        ac_required 1
 
501
        phase "suspend triggered via pm-suspend"
 
502
        suspend_system
 
503
fi
 
504
if [ "$test_ac" -eq 1 -a "$battery_count" -eq 0 ]; then
 
505
        ECHO "*** no BATTERY detected ac tests skipped ..."
 
506
elif [ "$test_ac" -eq 1 ]; then
 
507
        ac_required 0
 
508
        phase "suspend with AC disconnected"
 
509
        suspend_system
 
510
 
 
511
        ac_required 1
 
512
        phase "suspend with AC connected"
 
513
        suspend_system
 
514
        
 
515
        ac_transitions 1 0
 
516
        phase "loss of AC while suspended" \
 
517
              "please remove the AC cord while the machine is suspended"
 
518
        suspend_system
 
519
 
 
520
        ac_transitions 0 1
 
521
        phase "return of AC while suspended" \
 
522
              "please insert the AC cord while the machine is suspended"
 
523
        suspend_system
 
524
fi
 
525
if [ "$test_power" -eq 1 -a "$battery_count" -eq 0 ]; then
 
526
        ECHO "*** no BATTERY detected power test skipped ..."
 
527
elif [ "$test_power" -eq 1 ]; then
 
528
        save_timer_sleep="$timer_sleep"
 
529
        let timer_sleep="$args_power_sleep"
 
530
 
 
531
        ac_required 0
 
532
        phase "battery drain during suspend" \
 
533
              "calculates overall power drain during a long-term suspend"
 
534
 
 
535
        # get start values
 
536
        date_before=`date +%s`
 
537
        bat_before=`battery_capacity`
 
538
  
 
539
        # Suspend
 
540
        suspend_system
 
541
  
 
542
        # get end values
 
543
        date_after=`date +%s`
 
544
        bat_after=`battery_capacity`
 
545
 
 
546
        # do the calculations 
 
547
        let consumed="$bat_before - $bat_after"
 
548
        let elapsed="$date_after - $date_before"
 
549
        let usage="($consumed * 60*60) / $elapsed"
 
550
 
 
551
        # output the results
 
552
        ECHO "before: $bat_before mWh"
 
553
        ECHO "after: $bat_after mWh"
 
554
        ECHO "consumed: $consumed mW"
 
555
        ECHO "sleep seconds: $elapsed sec"
 
556
        ECHO "overall usage: $usage mW"
 
557
         
 
558
        report_battery="$usage mW"
 
559
 
 
560
        if [ $elapsed -lt 1200 ]
 
561
        then
 
562
                ECHO "WARNING: the suspend was less than 20 minutes"
 
563
                ECHO "         to get reliable numbers increase the sleep time"
 
564
                report_battery="$report_battery (unreliable)"
 
565
        fi
 
566
 
 
567
        timer_sleep="$save_timer_sleep"
 
568
fi
 
569
 
 
570
phase_interactive=0
 
571
if [ "$test_timed" -eq 1 ]; then
 
572
        save_timer_delay="$timer_delay"
 
573
        timer_delay=60
 
574
 
 
575
        ac_required 1
 
576
        phase "30 iteration variable delay suspend/resume stress test"
 
577
        while [ "$timer_delay" -gt 0 ]; do
 
578
                echo "delay $timer_delay ..."
 
579
                suspend_system
 
580
                delay_system
 
581
                let timer_delay="$timer_delay - 2"
 
582
        done
 
583
        timer_delay="$save_timer_delay"
 
584
fi
 
585
if [ "$test_repeat" -eq 1 ]; then
 
586
        ac_required 1
 
587
        phase "basic $args_repeat_iterations iteration suspend/resume stress test"
 
588
        run_suspend "$args_repeat_iterations"
 
589
fi
 
590
 
 
591
ac_check
 
592
 
 
593
#
 
594
# REPORT: final report stage.
 
595
#
 
596
report_this()
 
597
{       
 
598
        if [ "$2" != "" ]; then
 
599
                echo "      $1 $2"
 
600
        fi
 
601
}
 
602
if [ "$auto" -eq 0 ]; then
 
603
        echo ""
 
604
        echo "*** Please report your results on the Ubuntu WIKI:"
 
605
        echo "    https://wiki.ubuntu.com/KernelTeam/SuspendResumeTesting"
 
606
        echo ""
 
607
        report_this "Battery Consumption:" "$report_battery"
 
608
fi
 
609
 
 
610
# All suceessful, clean up.
 
611
rm -f "$LOGFILE"