summaryrefslogtreecommitdiff
diff options
authorAlbert Zhang <albert.zhang@canonical.com>2014-12-12 10:08:20 +0800
committerAlbert Zhang <albert.zhang@canonical.com>2014-12-12 10:08:20 +0800
commit8422db66c928cf1dd0cec5d5f0d50e82963f94d4 (patch)
tree620347a06b58ce5833fa66111e00f61a65866063
parent47b40a84eda042b83a4e129bb52beba15afcae34 (diff)
parentf0686a1a7f7d2a618e3f43a3d4b601b3d4e4bc7f (diff)
merged Sylvain's change to cleanup pm_test
-rwxr-xr-xbin/pm_test819
-rwxr-xr-xbin/pm_test_misc820
-rw-r--r--jobs/misc/misc-generic.txt31
-rw-r--r--jobs/somerville/somerville.txt.in110
-rw-r--r--whitelists/sutton-stress.whitelist1
5 files changed, 0 insertions, 1781 deletions
diff --git a/bin/pm_test b/bin/pm_test
deleted file mode 100755
index 18c0def..0000000
--- a/bin/pm_test
+++ /dev/null
@@ -1,819 +0,0 @@
-#!/usr/bin/env python3
-import logging
-import logging.handlers
-import os
-import pwd
-import re
-import shutil
-import subprocess
-import sys
-
-from argparse import ArgumentParser, SUPPRESS
-from calendar import timegm
-from datetime import datetime, timedelta
-from gi.repository import Gtk, GObject
-from time import time, localtime
-
-
-def main():
- """
- Run power management operation as many times as needed
- """
- args, extra_args = MyArgumentParser().parse()
-
- # Verify that script is run as root
- if os.getuid():
- sys.stderr.write('This script needs superuser '
- 'permissions to run correctly\n')
- sys.exit(1)
-
- #Obtain name of the invoking user.
- uid = os.getenv('SUDO_UID') or os.getenv('PKEXEC_UID')
- if not uid:
- sys.stderr.write('Unable to determine invoking user\n')
- sys.exit(1)
- username = pwd.getpwuid(int(uid)).pw_name
-
- LoggingConfiguration.set(args.log_level, args.log_filename, args.append)
- logging.debug('Invoking username: %s', username)
- logging.debug('Arguments: {0!r}'.format(args))
- logging.debug('Extra Arguments: {0!r}'.format(extra_args))
-
- try:
- operation = PowerManagementOperation(args, extra_args, user=username)
- operation.setup()
- operation.run()
- except (TestCancelled, TestFailed) as exception:
- operation.teardown()
- if isinstance(exception, TestFailed):
- logging.error(exception.args[0])
- message = exception.MESSAGE.format(args.pm_operation.capitalize())
- if args.silent:
- logging.info(message)
- else:
- title = '{0} test'.format(args.pm_operation.capitalize())
- MessageDialog(title, message, Gtk.MessageType.ERROR).run()
-
- return exception.RETURN_CODE
-
- return 0
-
-
-class PowerManagementOperation(object):
- SLEEP_TIME = 5
-
- def __init__(self, args, extra_args, user=None):
- self.args = args
- self.extra_args = extra_args
- self.user = user
-
- def setup(self):
- """
- Enable configuration file
- """
- # Enable autologin and sudo on first cycle
- if self.args.total == self.args.repetitions:
- AutoLoginConfigurator(user=self.user).enable()
- SudoersConfigurator(user=self.user).enable()
-
- # Schedule this script to be automatically executed
- # on startup to continue testing
- autostart_file = AutoStartFile(self.args, user=self.user)
- autostart_file.write()
-
- def run(self):
- """
- Run a power management iteration
- """
- logging.info('{0} operations remaining: {1}'
- .format(self.args.pm_operation, self.args.repetitions))
-
- self.check_last_cycle_duration()
- if self.args.repetitions > 0:
- self.run_pm_command()
- else:
- self.summary()
-
- def check_last_cycle_duration(self):
- """
- Make sure that last cycle duration was reasonable,
- that is, not too short, not too long
- """
- min_pm_time = timedelta(seconds=self.args.min_pm_time)
- max_pm_time = timedelta(seconds=self.args.max_pm_time)
- if self.args.pm_timestamp:
- pm_timestamp = datetime.fromtimestamp(self.args.pm_timestamp)
- now = datetime.now()
- pm_time = now - pm_timestamp
- if pm_time < min_pm_time:
- raise TestFailed('{0} time less than expected: {1} < {2}'
- .format(self.args.pm_operation.capitalize(),
- pm_time, min_pm_time))
- if pm_time > max_pm_time:
- raise TestFailed('{0} time greater than expected: {1} > {2}'
- .format(self.args.pm_operation.capitalize(),
- pm_time, max_pm_time))
-
- logging.info('{0} time: {1}'
- .format(self.args.pm_operation.capitalize(), pm_time))
-
- def run_pm_command(self):
- """
- Run power managment command and check result if needed
- """
- # Display information to user
- # and make it possible to cancel the test
- CountdownDialog(self.args.pm_operation,
- self.args.pm_delay,
- self.args.hardware_delay,
- self.args.total - self.args.repetitions,
- self.args.total).run()
-
- # A small sleep time is added to reboot and poweroff
- # so that script has time to return a value
- # (useful when running it as an automated test)
- command_str = ('sleep {0}; {1}'
- .format(self.SLEEP_TIME, self.args.pm_operation))
- if self.extra_args:
- command_str += ' {0}'.format(' '.join(self.extra_args))
-
- if self.args.pm_operation != 'reboot':
- WakeUpAlarm.set(seconds=self.args.wakeup)
-
- logging.info('Executing new {0!r} operation...'
- .format(self.args.pm_operation))
- logging.debug('Executing: {0!r}...'.format(command_str))
- subprocess.Popen(command_str, shell=True)
-
- def summary(self):
- """
- Gather hardware information for the last time,
- log execution time and exit
- """
- # Just gather hardware information one more time and exit
- CountdownDialog(self.args.pm_operation,
- self.args.pm_delay,
- self.args.hardware_delay,
- self.args.total - self.args.repetitions,
- self.args.total).run()
-
- self.teardown()
-
- # Log some time information
- start = datetime.fromtimestamp(self.args.start)
- end = datetime.now()
- if self.args.pm_operation == 'reboot':
- sleep_time = timedelta(seconds=self.SLEEP_TIME)
- else:
- sleep_time = timedelta(seconds=self.args.wakeup)
-
- wait_time = timedelta(seconds=(self.args.pm_delay
- + (self.args.hardware_delay)
- * self.args.total))
- average = (end - start - wait_time) / self.args.total - sleep_time
- time_message = ('Total elapsed time: {total}\n'
- 'Average recovery time: {average}'
- .format(total=end - start,
- average=average))
- logging.info(time_message)
-
- message = ('{0} test complete'
- .format(self.args.pm_operation.capitalize()))
- if self.args.silent:
- logging.info(message)
- else:
- title = '{0} test'.format(self.args.pm_operation.capitalize())
- MessageDialog(title, message).run()
-
- def teardown(self):
- """
- Restore configuration
- """
- # Don't execute this script again on next reboot
- autostart_file = AutoStartFile(self.args, user=self.user)
- autostart_file.remove()
-
- # Restore previous configuration
- SudoersConfigurator().disable()
- AutoLoginConfigurator().disable()
-
-
-class TestCancelled(Exception):
- RETURN_CODE = 1
- MESSAGE = '{0} test cancelled by user'
-
-
-class TestFailed(Exception):
- RETURN_CODE = 2
- MESSAGE = '{0} test failed'
-
-
-class WakeUpAlarm(object):
- ALARM_FILENAME = '/sys/class/rtc/rtc0/wakealarm'
- RTC_FILENAME = '/proc/driver/rtc'
-
- @classmethod
- def set(cls, minutes=0, seconds=0):
- """
- Calculate wakeup time and write it to BIOS
- """
- now = int(time())
- timeout = minutes * 60 + seconds
- wakeup_time_utc = now + timeout
- wakeup_time_local = timegm(localtime()) + timeout
-
- subprocess.check_call('echo 0 > %s' % cls.ALARM_FILENAME, shell=True)
- subprocess.check_call('echo %d > %s'
- % (wakeup_time_utc, cls.ALARM_FILENAME),
- shell=True)
-
- with open(cls.ALARM_FILENAME) as alarm_file:
- wakeup_time_stored_str = alarm_file.read()
-
- if not re.match('\d+', wakeup_time_stored_str):
- subprocess.check_call('echo "+%d" > %s'
- % (timeout, cls.ALARM_FILENAME),
- shell=True)
- with open(cls.ALARM_FILENAME) as alarm_file2:
- wakeup_time_stored_str = alarm_file2.read()
- if not re.match('\d+', wakeup_time_stored_str):
- logging.error('Invalid wakeup time format: {0!r}'
- .format(wakeup_time_stored_str))
- sys.exit(1)
-
- wakeup_time_stored = int(wakeup_time_stored_str)
- try:
- logging.debug('Wakeup timestamp: {0} ({1})'
- .format(wakeup_time_stored,
- datetime.fromtimestamp(
- wakeup_time_stored).strftime('%c')))
- except ValueError as e:
- logging.error(e)
- sys.exit(1)
-
- if ((abs(wakeup_time_utc - wakeup_time_stored) > 1) and
- (abs(wakeup_time_local - wakeup_time_stored) > 1)):
- logging.error('Wakeup time not stored correctly')
- sys.exit(1)
-
- with open(cls.RTC_FILENAME) as rtc_file:
- separator_regex = re.compile('\s+:\s+')
- rtc_data = dict([separator_regex.split(line.rstrip())
- for line in rtc_file])
- logging.debug('RTC data:\n{0}'
- .format('\n'.join(['- {0}: {1}'.format(*pair)
- for pair in rtc_data.items()])))
-
- # Verify wakeup time has been set properly
- # by looking into the alarm_IRQ and alrm_date field
- if rtc_data['alarm_IRQ'] != 'yes':
- logging.error('alarm_IRQ not set properly: {0}'
- .format(rtc_data['alarm_IRQ']))
- sys.exit(1)
-
- if '*' in rtc_data['alrm_date']:
- logging.error('alrm_date not set properly: {0}'
- .format(rtc_data['alrm_date']))
- sys.exit(1)
-
-
-class Command(object):
- """
- Simple subprocess.Popen wrapper to run shell commands
- and log their output
- """
- def __init__(self, command_str, verbose=True):
- self.command_str = command_str
- self.verbose = verbose
-
- self.process = None
- self.stdout = None
- self.stderr = None
- self.time = None
-
- def run(self):
- """
- Execute shell command and return output and status
- """
- logging.debug('Executing: {0!r}...'.format(self.command_str))
-
- self.process = subprocess.Popen(self.command_str,
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- start = datetime.now()
- result = self.process.communicate()
- end = datetime.now()
- self.time = end - start
-
- if self.verbose:
- stdout, stderr = result
- message = ['Output:\n'
- '- returncode:\n{0}'.format(self.process.returncode)]
- if stdout:
- if type(stdout) is bytes:
- stdout = stdout.decode('utf-8')
- message.append('- stdout:\n{0}'.format(stdout))
- if stderr:
- if type(stderr) is bytes:
- stderr = stderr.decode('utf-8')
- message.append('- stderr:\n{0}'.format(stderr))
- logging.debug('\n'.join(message))
-
- self.stdout = stdout
- self.stderr = stderr
-
- return self
-
-
-class CountdownDialog(Gtk.Dialog):
- """
- Dialog that shows the amount of progress in the reboot test
- and lets the user cancel it if needed
- """
- def __init__(self, pm_operation, pm_delay, hardware_delay,
- iterations, iterations_count):
- self.pm_operation = pm_operation
- title = '{0} test'.format(pm_operation.capitalize())
-
- buttons = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,)
- super(CountdownDialog, self).__init__(title=title,
- buttons=buttons)
- self.set_default_response(Gtk.ResponseType.CANCEL)
- self.set_resizable(False)
- self.set_position(Gtk.WindowPosition.CENTER)
-
- progress_bar = Gtk.ProgressBar()
- progress_bar.set_fraction(iterations / float(iterations_count))
- progress_bar.set_text('{0}/{1}'
- .format(iterations, iterations_count))
- progress_bar.set_show_text(True)
- self.vbox.pack_start(progress_bar, True, True, 0)
-
- operation_event = {'template': ('Next {0} in {{time}} seconds...'
- .format(self.pm_operation)),
- 'timeout': pm_delay}
- hardware_info_event = \
- {'template': 'Gathering hardware information in {time} seconds...',
- 'timeout': hardware_delay,
- 'callback': self.on_hardware_info_timeout_cb}
-
- if iterations == 0:
- # In first iteration, gather hardware information directly
- # and perform pm-operation
- self.on_hardware_info_timeout_cb()
- self.events = [operation_event]
- elif iterations < iterations_count:
- # In last iteration, wait before gathering hardware information
- # and perform pm-operation
- self.events = [operation_event,
- hardware_info_event]
- else:
- # In last iteration, wait before gathering hardware information
- # and finish the test
- self.events = [hardware_info_event]
-
- self.label = Gtk.Label()
- self.vbox.pack_start(self.label, True, True, 0)
- self.show_all()
-
- def run(self):
- """
- Set label text and run dialog
- """
- self.schedule_next_event()
- response = super(CountdownDialog, self).run()
- self.destroy()
-
- if response != Gtk.ResponseType.ACCEPT:
- raise TestCancelled()
-
- def schedule_next_event(self):
- """
- Schedule next timed event
- """
- if self.events:
- self.event = self.events.pop()
- self.timeout_counter = self.event.get('timeout', 0)
- self.label.set_text(self.event['template']
- .format(time=self.timeout_counter))
- GObject.timeout_add_seconds(1, self.on_timeout_cb)
- else:
- # Return Accept response
- # if there are no other events scheduled
- self.response(Gtk.ResponseType.ACCEPT)
-
- def on_timeout_cb(self):
- """
- Set label properly and use callback method if needed
- """
- if self.timeout_counter > 0:
- self.label.set_text(self.event['template']
- .format(time=self.timeout_counter))
- self.timeout_counter -= 1
- return True
-
- # Call calback if defined
- callback = self.event.get('callback')
- if callback:
- callback()
-
- # Schedule next event if needed
- self.schedule_next_event()
-
- return False
-
- def on_hardware_info_timeout_cb(self):
- """
- Gather hardware information and print it to logs
- """
- logging.info('Gathering hardware information...')
- logging.debug('Networking:\n'
- '{network}\n'
- '{ethernet}\n'
- '{ifconfig}\n'
- '{iwconfig}'
- .format(network=(Command('lspci | grep Network')
- .run().stdout),
- ethernet=(Command('lspci | grep Ethernet')
- .run().stdout),
- ifconfig=(Command("ifconfig -a | grep -A1 '^\w'")
- .run().stdout),
- iwconfig=(Command("iwconfig | grep -A1 '^\w'")
- .run().stdout)))
- logging.debug('Bluetooth Device:\n'
- '{hciconfig}'
- .format(hciconfig=(Command("hciconfig -a "
- "| grep -A2 '^\w'")
- .run().stdout)))
- logging.debug('Video Card:\n'
- '{lspci}'
- .format(lspci=Command('lspci | grep VGA').run().stdout))
- logging.debug('Touchpad and Keyboard:\n'
- '{xinput}'
- .format(xinput=Command(
- 'xinput list --name-only | sort').run().stdout))
- logging.debug('Pulse Audio Sink:\n'
- '{pactl_sink}'
- .format(pactl_sink=(Command('pactl list | grep Sink')
- .run().stdout)))
- logging.debug('Pulse Audio Source:\n'
- '{pactl_source}'
- .format(pactl_source=(Command('pactl list | grep Source')
- .run().stdout)))
-
- # Check kernel logs using firmware test suite
- command = Command('fwts -r stdout klog oops').run()
- if command.process.returncode != 0:
- # Don't abort the test loop,
- # errors can be retrieved by pm_log_check
- logging.error('Problem found in logs by fwts')
-
-
-class MessageDialog(object):
- """
- Simple wrapper aroung Gtk.MessageDialog
- """
- def __init__(self, title, message, type=Gtk.MessageType.INFO):
- self.title = title
- self.message = message
- self.type = type
-
- def run(self):
- dialog = Gtk.MessageDialog(buttons=Gtk.ButtonsType.OK,
- message_format=self.message,
- type=self.type)
- logging.info(self.message)
- dialog.set_title(self.title)
- dialog.run()
- dialog.destroy()
-
-
-class AutoLoginConfigurator(object):
- """
- Enable/disable autologin configuration
- to make sure that reboot test will work properly
- """
- CONFIG_FILENAME = '/etc/lightdm/lightdm.conf'
- TEMPLATE = """
-[SeatDefaults]
-greeter-session=unity-greeter
-user-session=ubuntu
-autologin-user={username}
-autologin-user-timeout=0
-"""
-
- def __init__(self, user=None):
- self.user = user
-
- def enable(self):
- """
- Make sure user will autologin in next reboot
- """
- logging.debug('Enabling autologin for this user...')
- if os.path.exists(self.CONFIG_FILENAME):
- for backup_filename in self.generate_backup_filename():
- if not os.path.exists(backup_filename):
- shutil.copyfile(self.CONFIG_FILENAME, backup_filename)
- shutil.copystat(self.CONFIG_FILENAME, backup_filename)
- break
-
- with open(self.CONFIG_FILENAME, 'w') as f:
- f.write(self.TEMPLATE.format(username=self.user))
-
- def disable(self):
- """
- Remove latest configuration file
- and use the same configuration that was in place
- before running the test
- """
- logging.debug('Restoring autologin configuration...')
- backup_filename = None
- for filename in self.generate_backup_filename():
- if not os.path.exists(filename):
- break
- backup_filename = filename
-
- if backup_filename:
- shutil.copy(backup_filename, self.CONFIG_FILENAME)
- os.remove(backup_filename)
- else:
- os.remove(self.CONFIG_FILENAME)
-
- def generate_backup_filename(self):
- backup_filename = self.CONFIG_FILENAME + '.bak'
- yield backup_filename
-
- index = 0
- while True:
- index += 1
- backup_filename = (self.CONFIG_FILENAME
- + '.bak.{0}'.format(index))
- yield backup_filename
-
-
-class SudoersConfigurator(object):
- """
- Enable/disable reboot test to be executed as root
- to make sure that reboot test works properly
- """
- MARK = '# Automatically added by pm.py'
- SUDOERS = '/etc/sudoers'
-
- def __init__(self, user=None):
- self.user = user
-
- def enable(self):
- """
- Make sure that user will be allowed to execute reboot test as root
- """
- logging.debug('Enabling user to execute test as root...')
- command = ("sed -i -e '$a{mark}\\n"
- "{user} ALL=NOPASSWD: /usr/bin/python' "
- "{filename}".format(mark=self.MARK,
- user=self.user,
- script=os.path.realpath(__file__),
- filename=self.SUDOERS))
-
- Command(command, verbose=False).run()
-
- def disable(self):
- """
- Revert sudoers configuration changes
- """
- logging.debug('Restoring sudoers configuration...')
- command = (("sed -i -e '/{mark}/,+1d' "
- "{filename}")
- .format(mark=self.MARK,
- filename=self.SUDOERS))
- Command(command, verbose=False).run()
-
-
-class AutoStartFile(object):
- """
- Generate autostart file contents and write it to proper location
- """
- TEMPLATE = """
-[Desktop Entry]
-Name={pm_operation} test
-Comment=Verify {pm_operation} works properly
-Exec=sudo /usr/bin/python {script} -r {repetitions} -w {wakeup} --hardware-delay {hardware_delay} --pm-delay {pm_delay} --min-pm-time {min_pm_time} --max-pm-time {max_pm_time} --append --total {total} --start {start} --pm-timestamp {pm_timestamp} {silent} --log-level={log_level} --log-dir={log_dir} {pm_operation}
-Type=Application
-X-GNOME-Autostart-enabled=true
-Hidden=false
-"""
-
- def __init__(self, args, user=None):
- self.args = args
- self.user = user
-
- # Generate desktop filename
- # based on environment variables
- username = self.user
- default_config_directory = os.path.expanduser('~{0}/.config'
- .format(username))
- config_directory = os.getenv('XDG_CONFIG_HOME',
- default_config_directory)
- autostart_directory = os.path.join(config_directory, 'autostart')
- if not os.path.exists(autostart_directory):
- os.makedirs(autostart_directory)
-
- basename = '{0}.desktop'.format(os.path.basename(__file__))
- self.desktop_filename = os.path.join(autostart_directory,
- basename)
-
- def write(self):
- """
- Write autostart file to execute the script on startup
- """
- logging.debug('Writing desktop file ({0!r})...'
- .format(self.desktop_filename))
-
- contents = (self.TEMPLATE
- .format(script=os.path.realpath(__file__),
- repetitions=self.args.repetitions - 1,
- wakeup=self.args.wakeup,
- hardware_delay=self.args.hardware_delay,
- pm_delay=self.args.pm_delay,
- min_pm_time=self.args.min_pm_time,
- max_pm_time=self.args.max_pm_time,
- total=self.args.total,
- start=self.args.start,
- pm_timestamp=int(time()),
- silent='--silent' if self.args.silent else '',
- log_level=self.args.log_level_str,
- log_dir=self.args.log_dir,
- pm_operation=self.args.pm_operation))
- logging.debug(contents)
-
- with open(self.desktop_filename, 'w') as f:
- f.write(contents)
-
- def remove(self):
- """
- Remove autostart file to avoid executing the script on startup
- """
- if os.path.exists(self.desktop_filename):
- logging.debug('Removing desktop file ({0!r})...'
- .format(self.desktop_filename))
- os.remove(self.desktop_filename)
-
-
-class LoggingConfiguration(object):
- @classmethod
- def set(cls, log_level, log_filename, append):
- """
- Configure a rotating file logger
- """
- logger = logging.getLogger()
- logger.setLevel(logging.DEBUG)
-
- # Log to sys.stderr using log level passed through command line
- if log_level != logging.NOTSET:
- log_handler = logging.StreamHandler()
- formatter = logging.Formatter('%(levelname)-8s %(message)s')
- log_handler.setFormatter(formatter)
- log_handler.setLevel(log_level)
- logger.addHandler(log_handler)
-
- # Log to rotating file using DEBUG log level
- log_handler = logging.handlers.RotatingFileHandler(log_filename,
- mode='a+',
- backupCount=3)
- formatter = logging.Formatter('%(asctime)s %(levelname)-8s '
- '%(message)s')
- log_handler.setFormatter(formatter)
- log_handler.setLevel(logging.DEBUG)
- logger.addHandler(log_handler)
-
- if not append:
- # Create a new log file on every new
- # (i.e. not scheduled) invocation
- log_handler.doRollover()
-
-
-class MyArgumentParser(object):
- """
- Command-line argument parser
- """
- def __init__(self):
- """
- Create parser object
- """
- pm_operations = ('poweroff', 'reboot')
- description = 'Run power management operation as many times as needed'
- epilog = ('Unknown arguments will be passed '
- 'to the underlying command: poweroff or reboot.')
- parser = ArgumentParser(description=description, epilog=epilog)
- parser.add_argument('-r', '--repetitions', type=int, default=1,
- help=('Number of times that the power management '
- 'operation has to be repeated '
- '(%(default)s by default)'))
- parser.add_argument('-w', '--wakeup', type=int, default=60,
- help=('Timeout in seconds for the wakeup alarm '
- '(%(default)s by default). '
- "Note: wakeup alarm won't be scheduled "
- 'for reboot.'))
- parser.add_argument('--min-pm-time', dest='min_pm_time',
- type=int, default=0,
- help=('Minimum time in seconds that '
- 'it should take the power management '
- 'operation each cycle (0 for reboot and '
- 'wakeup time minus two seconds '
- 'for the other power management operations '
- 'by default)'))
- parser.add_argument('--max-pm-time', dest='max_pm_time',
- type=int, default=300,
- help=('Maximum time in seconds '
- 'that it should take '
- 'the power management operation each cycle '
- '(%(default)s by default)'))
- parser.add_argument('--pm-delay', dest='pm_delay',
- type=int, default=5,
- help=('Delay in seconds '
- 'after hardware information '
- 'has been gathered and before executing '
- 'the power management operation '
- '(%(default)s by default)'))
- parser.add_argument('--hardware-delay', dest='hardware_delay',
- type=int, default=30,
- help=('Delay in seconds before gathering hardware '
- 'information (%(default)s by default)'))
- parser.add_argument('--silent', action='store_true',
- help=("Don't display any dialog "
- 'when test is complete '
- 'to let the script be used '
- 'in automated tests'))
- log_levels = ['notset', 'debug', 'info',
- 'warning', 'error', 'critical']
- parser.add_argument('--log-level', dest='log_level_str',
- default='info', choices=log_levels,
- help=('Log level. '
- 'One of {0} or {1} (%(default)s by default)'
- .format(', '.join(log_levels[:-1]),
- log_levels[-1])))
- parser.add_argument('--log-dir', dest='log_dir', default='/var/log',
- help=('Path to the directory to store log files'))
- parser.add_argument('pm_operation', choices=pm_operations,
- help=('Power management operation to be performed '
- '(one of {0} or {1!r})'
- .format(', '.join(map(repr,
- pm_operations[:-1])),
- pm_operations[-1])))
-
- # Test timestamps
- parser.add_argument('--start', type=int, default=0, help=SUPPRESS)
- parser.add_argument('--pm-timestamp', dest='pm_timestamp',
- type=int, default=0, help=SUPPRESS)
-
- # Append to log on subsequent startups
- parser.add_argument('--append', action='store_true',
- default=False, help=SUPPRESS)
-
- # Total number of iterations initially passed through the command line
- parser.add_argument('--total', type=int, default=0, help=SUPPRESS)
- self.parser = parser
-
- def parse(self):
- """
- Parse command-line arguments
- """
- args, extra_args = self.parser.parse_known_args()
- args.log_level = getattr(logging, args.log_level_str.upper())
-
- # Total number of repetitions
- # is the number of repetitions passed through the command line
- # the first time the script is executed
- if not args.total:
- args.total = args.repetitions
-
- # Test start time automatically set on first iteration
- if not args.start:
- args.start = int(time())
-
- # Wakeup time set to 0 for 'reboot'
- # since wakeup alarm won't be scheduled
- if args.pm_operation == 'reboot':
- args.wakeup = 0
- args.min_pm_time = 0
-
- # Minimum time for each power management operation
- # is set to the wakeup time
- if not args.min_pm_time:
- min_pm_time = args.wakeup - 2
- if min_pm_time < 0:
- min_pm_time = 0
- args.min_pm_time = min_pm_time
-
- # Log filename shows clearly the type of test (pm_operation)
- # and the times it was repeated (repetitions)
- args.log_filename = os.path.join(args.log_dir,
- ('{0}.{1}.{2}.log'
- .format(os.path.basename(__file__),
- args.pm_operation,
- args.total)))
- return args, extra_args
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/bin/pm_test_misc b/bin/pm_test_misc
deleted file mode 100755
index 397e955..0000000
--- a/bin/pm_test_misc
+++ /dev/null
@@ -1,820 +0,0 @@
-#!/usr/bin/env python3
-import logging
-import logging.handlers
-import os
-import pwd
-import re
-import shutil
-import subprocess
-import sys
-
-from argparse import ArgumentParser, SUPPRESS
-from calendar import timegm
-from datetime import datetime, timedelta
-from gi.repository import Gtk, GObject
-from time import time, localtime
-
-
-def main():
- """
- Run power management operation as many times as needed
- """
- args, extra_args = MyArgumentParser().parse()
-
- # Verify that script is run as root
- if os.getuid():
- sys.stderr.write('This script needs superuser '
- 'permissions to run correctly\n')
- sys.exit(1)
-
- #Obtain name of the invoking user.
- uid = os.getenv('SUDO_UID') or os.getenv('PKEXEC_UID')
- if not uid:
- sys.stderr.write('Unable to determine invoking user\n')
- sys.exit(1)
- username = pwd.getpwuid(int(uid)).pw_name
-
- LoggingConfiguration.set(args.log_level, args.log_filename, args.append)
- logging.debug('Invoking username: %s', username)
- logging.debug('Arguments: {0!r}'.format(args))
- logging.debug('Extra Arguments: {0!r}'.format(extra_args))
-
- try:
- operation = PowerManagementOperation(args, extra_args, user=username)
- operation.setup()
- operation.run()
- except (TestCancelled, TestFailed) as exception:
- operation.teardown()
- if isinstance(exception, TestFailed):
- logging.error(exception.args[0])
- message = exception.MESSAGE.format(args.pm_operation.capitalize())
- if args.silent:
- logging.info(message)
- else:
- title = '{0} test'.format(args.pm_operation.capitalize())
- MessageDialog(title, message, Gtk.MessageType.ERROR).run()
-
- return exception.RETURN_CODE
-
- return 0
-
-
-class PowerManagementOperation(object):
- SLEEP_TIME = 5
-
- def __init__(self, args, extra_args, user=None):
- self.args = args
- self.extra_args = extra_args
- self.user = user
-
- def setup(self):
- """
- Enable configuration file
- """
- # Enable autologin and sudo on first cycle
- if self.args.total == self.args.repetitions:
- AutoLoginConfigurator(user=self.user).enable()
- SudoersConfigurator(user=self.user).enable()
-
- # Schedule this script to be automatically executed
- # on startup to continue testing
- autostart_file = AutoStartFile(self.args, user=self.user)
- autostart_file.write()
-
- def run(self):
- """
- Run a power management iteration
- """
- logging.info('{0} operations remaining: {1}'
- .format(self.args.pm_operation, self.args.repetitions))
-
- self.check_last_cycle_duration()
- if self.args.repetitions > 0:
- self.run_pm_command()
- else:
- self.summary()
-
- def check_last_cycle_duration(self):
- """
- Make sure that last cycle duration was reasonable,
- that is, not too short, not too long
- """
- min_pm_time = timedelta(seconds=self.args.min_pm_time)
- max_pm_time = timedelta(seconds=self.args.max_pm_time)
- if self.args.pm_timestamp:
- pm_timestamp = datetime.fromtimestamp(self.args.pm_timestamp)
- now = datetime.now()
- pm_time = now - pm_timestamp
- if pm_time < min_pm_time:
- raise TestFailed('{0} time less than expected: {1} < {2}'
- .format(self.args.pm_operation.capitalize(),
- pm_time, min_pm_time))
- if pm_time > max_pm_time:
- raise TestFailed('{0} time greater than expected: {1} > {2}'
- .format(self.args.pm_operation.capitalize(),
- pm_time, max_pm_time))
-
- logging.info('{0} time: {1}'
- .format(self.args.pm_operation.capitalize(), pm_time))
-
- def run_pm_command(self):
- """
- Run power managment command and check result if needed
- """
- # Display information to user
- # and make it possible to cancel the test
- CountdownDialog(self.args.pm_operation,
- self.args.pm_delay,
- self.args.hardware_delay,
- self.args.total - self.args.repetitions,
- self.args.total).run()
-
- # A small sleep time is added to reboot and poweroff
- # so that script has time to return a value
- # (useful when running it as an automated test)
- command_str = ('sleep {0}; {1}'
- .format(self.SLEEP_TIME, self.args.pm_operation))
- if self.extra_args:
- command_str += ' {0}'.format(' '.join(self.extra_args))
-
- if self.args.pm_operation != 'reboot':
- WakeUpAlarm.set(seconds=self.args.wakeup)
-
- logging.info('Executing new {0!r} operation...'
- .format(self.args.pm_operation))
- logging.debug('Executing: {0!r}...'.format(command_str))
- subprocess.Popen(command_str, shell=True)
-
- def summary(self):
- """
- Gather hardware information for the last time,
- log execution time and exit
- """
- # Just gather hardware information one more time and exit
- CountdownDialog(self.args.pm_operation,
- self.args.pm_delay,
- self.args.hardware_delay,
- self.args.total - self.args.repetitions,
- self.args.total).run()
-
- self.teardown()
-
- # Log some time information
- start = datetime.fromtimestamp(self.args.start)
- end = datetime.now()
- if self.args.pm_operation == 'reboot':
- sleep_time = timedelta(seconds=self.SLEEP_TIME)
- else:
- sleep_time = timedelta(seconds=self.args.wakeup)
-
- wait_time = timedelta(seconds=(self.args.pm_delay
- + (self.args.hardware_delay)
- * self.args.total))
- average = (end - start - wait_time) / self.args.total - sleep_time
- time_message = ('Total elapsed time: {total}\n'
- 'Average recovery time: {average}'
- .format(total=end - start,
- average=average))
- logging.info(time_message)
-
- message = ('{0} test complete'
- .format(self.args.pm_operation.capitalize()))
- if self.args.silent:
- logging.info(message)
- else:
- title = '{0} test'.format(self.args.pm_operation.capitalize())
- MessageDialog(title, message).run()
-
- def teardown(self):
- """
- Restore configuration
- """
- # Don't execute this script again on next reboot
- autostart_file = AutoStartFile(self.args, user=self.user)
- autostart_file.remove()
-
- # Restore previous configuration
- SudoersConfigurator().disable()
- AutoLoginConfigurator().disable()
-
-
-class TestCancelled(Exception):
- RETURN_CODE = 1
- MESSAGE = '{0} test cancelled by user'
-
-
-class TestFailed(Exception):
- RETURN_CODE = 2
- MESSAGE = '{0} test failed'
-
-
-class WakeUpAlarm(object):
- ALARM_FILENAME = '/sys/class/rtc/rtc0/wakealarm'
- RTC_FILENAME = '/proc/driver/rtc'
-
- @classmethod
- def set(cls, minutes=0, seconds=0):
- """
- Calculate wakeup time and write it to BIOS
- """
- now = int(time())
- timeout = minutes * 60 + seconds
- wakeup_time_utc = now + timeout
- wakeup_time_local = timegm(localtime()) + timeout
-
- subprocess.check_call('echo 0 > %s' % cls.ALARM_FILENAME, shell=True)
- subprocess.check_call('echo %d > %s'
- % (wakeup_time_utc, cls.ALARM_FILENAME),
- shell=True)
-
- with open(cls.ALARM_FILENAME) as alarm_file:
- wakeup_time_stored_str = alarm_file.read()
-
- if not re.match('\d+', wakeup_time_stored_str):
- subprocess.check_call('echo "+%d" > %s'
- % (timeout, cls.ALARM_FILENAME),
- shell=True)
- with open(cls.ALARM_FILENAME) as alarm_file2:
- wakeup_time_stored_str = alarm_file2.read()
- if not re.match('\d+', wakeup_time_stored_str):
- logging.error('Invalid wakeup time format: {0!r}'
- .format(wakeup_time_stored_str))
- sys.exit(1)
-
- wakeup_time_stored = int(wakeup_time_stored_str)
- try:
- logging.debug('Wakeup timestamp: {0} ({1})'
- .format(wakeup_time_stored,
- datetime.fromtimestamp(
- wakeup_time_stored).strftime('%c')))
- except ValueError as e:
- logging.error(e)
- sys.exit(1)
-
- if ((abs(wakeup_time_utc - wakeup_time_stored) > 1) and
- (abs(wakeup_time_local - wakeup_time_stored) > 1)):
- logging.error('Wakeup time not stored correctly')
- sys.exit(1)
-
- with open(cls.RTC_FILENAME) as rtc_file:
- separator_regex = re.compile('\s+:\s+')
- rtc_data = dict([separator_regex.split(line.rstrip())
- for line in rtc_file])
- logging.debug('RTC data:\n{0}'
- .format('\n'.join(['- {0}: {1}'.format(*pair)
- for pair in rtc_data.items()])))
-
- # Verify wakeup time has been set properly
- # by looking into the alarm_IRQ and alrm_date field
- if rtc_data['alarm_IRQ'] != 'yes':
- logging.error('alarm_IRQ not set properly: {0}'
- .format(rtc_data['alarm_IRQ']))
- sys.exit(1)
-
- if '*' in rtc_data['alrm_date']:
- logging.error('alrm_date not set properly: {0}'
- .format(rtc_data['alrm_date']))
- sys.exit(1)
-
-
-class Command(object):
- """
- Simple subprocess.Popen wrapper to run shell commands
- and log their output
- """
- def __init__(self, command_str, verbose=True):
- self.command_str = command_str
- self.verbose = verbose
-
- self.process = None
- self.stdout = None
- self.stderr = None
- self.time = None
-
- def run(self):
- """
- Execute shell command and return output and status
- """
- logging.debug('Executing: {0!r}...'.format(self.command_str))
-
- self.process = subprocess.Popen(self.command_str,
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- start = datetime.now()
- result = self.process.communicate()
- end = datetime.now()
- self.time = end - start
-
- if self.verbose:
- stdout, stderr = result
- message = ['Output:\n'
- '- returncode:\n{0}'.format(self.process.returncode)]
- if stdout:
- if type(stdout) is bytes:
- stdout = stdout.decode('utf-8')
- message.append('- stdout:\n{0}'.format(stdout))
- if stderr:
- if type(stderr) is bytes:
- stderr = stderr.decode('utf-8')
- message.append('- stderr:\n{0}'.format(stderr))
- logging.debug('\n'.join(message))
-
- self.stdout = stdout
- self.stderr = stderr
-
- return self
-
-
-class CountdownDialog(Gtk.Dialog):
- """
- Dialog that shows the amount of progress in the reboot test
- and lets the user cancel it if needed
- """
- def __init__(self, pm_operation, pm_delay, hardware_delay,
- iterations, iterations_count):
- self.pm_operation = pm_operation
- title = '{0} test'.format(pm_operation.capitalize())
-
- buttons = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,)
- super(CountdownDialog, self).__init__(title=title,
- buttons=buttons)
- self.set_default_response(Gtk.ResponseType.CANCEL)
- self.set_resizable(False)
- self.set_position(Gtk.WindowPosition.CENTER)
-
- progress_bar = Gtk.ProgressBar()
- progress_bar.set_fraction(iterations / float(iterations_count))
- progress_bar.set_text('{0}/{1}'
- .format(iterations, iterations_count))
- progress_bar.set_show_text(True)
- self.vbox.pack_start(progress_bar, True, True, 0)
-
- operation_event = {'template': ('Next {0} in {{time}} seconds...'
- .format(self.pm_operation)),
- 'timeout': pm_delay}
- hardware_info_event = \
- {'template': 'Gathering hardware information in {time} seconds...',
- 'timeout': hardware_delay,
- 'callback': self.on_hardware_info_timeout_cb}
-
- if iterations == 0:
- # In first iteration, gather hardware information directly
- # and perform pm-operation
- self.on_hardware_info_timeout_cb()
- self.events = [operation_event]
- elif iterations < iterations_count:
- # In last iteration, wait before gathering hardware information
- # and perform pm-operation
- self.events = [operation_event,
- hardware_info_event]
- else:
- # In last iteration, wait before gathering hardware information
- # and finish the test
- self.events = [hardware_info_event]
-
- self.label = Gtk.Label()
- self.vbox.pack_start(self.label, True, True, 0)
- self.show_all()
-
- def run(self):
- """
- Set label text and run dialog
- """
- self.schedule_next_event()
- response = super(CountdownDialog, self).run()
- self.destroy()
-
- if response != Gtk.ResponseType.ACCEPT:
- raise TestCancelled()
-
- def schedule_next_event(self):
- """
- Schedule next timed event
- """
- if self.events:
- self.event = self.events.pop()
- self.timeout_counter = self.event.get('timeout', 0)
- self.label.set_text(self.event['template']
- .format(time=self.timeout_counter))
- GObject.timeout_add_seconds(1, self.on_timeout_cb)
- else:
- # Return Accept response
- # if there are no other events scheduled
- self.response(Gtk.ResponseType.ACCEPT)
-
- def on_timeout_cb(self):
- """
- Set label properly and use callback method if needed
- """
- if self.timeout_counter > 0:
- self.label.set_text(self.event['template']
- .format(time=self.timeout_counter))
- self.timeout_counter -= 1
- return True
-
- # Call calback if defined
- callback = self.event.get('callback')
- if callback:
- callback()
-
- # Schedule next event if needed
- self.schedule_next_event()
-
- return False
-
- def on_hardware_info_timeout_cb(self):
- """
- Gather hardware information and print it to logs
- """
- logging.info('Gathering hardware information...')
- logging.debug('Networking:\n'
- '{network}\n'
- '{ethernet}\n'
- '{ifconfig}\n'
- '{iwconfig}'
- .format(network=(Command('lspci | grep Network')
- .run().stdout),
- ethernet=(Command('lspci | grep Ethernet')
- .run().stdout),
- ifconfig=(Command("ifconfig -a | grep -A1 '^\w'")
- .run().stdout),
- iwconfig=(Command("iwconfig | grep -A1 '^\w'")
- .run().stdout)))
- logging.debug('Bluetooth Device:\n'
- '{hciconfig}'
- .format(hciconfig=(Command("hciconfig -a "
- "| grep -A2 '^\w'")
- .run().stdout)))
- logging.debug('Video Card:\n'
- '{lspci}'
- .format(lspci=Command('lspci | grep VGA').run().stdout))
- logging.debug('Touchpad and Keyboard:\n'
- '{xinput}'
- .format(xinput=Command(
- 'xinput list --name-only | sort').run().stdout))
- logging.debug('Pulse Audio Sink:\n'
- '{pactl_sink}'
- .format(pactl_sink=(Command('pactl list | grep Sink')
- .run().stdout)))
- logging.debug('Pulse Audio Source:\n'
- '{pactl_source}'
- .format(pactl_source=(Command('pactl list | grep Source')
- .run().stdout)))
-
- # Check kernel logs using firmware test suite
- command = Command('fwts -r stdout klog oops').run()
- if command.process.returncode != 0:
- # Don't abort the test loop,
- # errors can be retrieved by pm_log_check
- logging.error('Problem found in logs by fwts')
-
-
-class MessageDialog(object):
- """
- Simple wrapper aroung Gtk.MessageDialog
- """
- def __init__(self, title, message, type=Gtk.MessageType.INFO):
- self.title = title
- self.message = message
- self.type = type
-
- def run(self):
- dialog = Gtk.MessageDialog(buttons=Gtk.ButtonsType.OK,
- message_format=self.message,
- type=self.type)
- logging.info(self.message)
- dialog.set_title(self.title)
- dialog.run()
- dialog.destroy()
-
-
-class AutoLoginConfigurator(object):
- """
- Enable/disable autologin configuration
- to make sure that reboot test will work properly
- """
- CONFIG_FILENAME = '/etc/lightdm/lightdm.conf'
- TEMPLATE = """
-[SeatDefaults]
-greeter-session=unity-greeter
-user-session=ubuntu
-autologin-user={username}
-autologin-user-timeout=0
-"""
-
- def __init__(self, user=None):
- self.user = user
-
- def enable(self):
- """
- Make sure user will autologin in next reboot
- """
- logging.debug('Enabling autologin for this user...')
- if os.path.exists(self.CONFIG_FILENAME):
- for backup_filename in self.generate_backup_filename():
- if not os.path.exists(backup_filename):
- shutil.copyfile(self.CONFIG_FILENAME, backup_filename)
- shutil.copystat(self.CONFIG_FILENAME, backup_filename)
- break
-
- with open(self.CONFIG_FILENAME, 'w') as f:
- f.write(self.TEMPLATE.format(username=self.user))
-
- def disable(self):
- """
- Remove latest configuration file
- and use the same configuration that was in place
- before running the test
- """
- logging.debug('Restoring autologin configuration...')
- backup_filename = None
- for filename in self.generate_backup_filename():
- if not os.path.exists(filename):
- break
- backup_filename = filename
-
- if backup_filename:
- shutil.copy(backup_filename, self.CONFIG_FILENAME)
- os.remove(backup_filename)
- else:
- os.remove(self.CONFIG_FILENAME)
-
- def generate_backup_filename(self):
- backup_filename = self.CONFIG_FILENAME + '.bak'
- yield backup_filename
-
- index = 0
- while True:
- index += 1
- backup_filename = (self.CONFIG_FILENAME
- + '.bak.{0}'.format(index))
- yield backup_filename
-
-
-class SudoersConfigurator(object):
- """
- Enable/disable reboot test to be executed as root
- to make sure that reboot test works properly
- """
- MARK = '# Automatically added by pm.py'
- SUDOERS = '/etc/sudoers'
-
- def __init__(self, user=None):
- self.user = user
-
- def enable(self):
- """
- Make sure that user will be allowed to execute reboot test as root
- """
- logging.debug('Enabling user to execute test as root...')
- command = ("sed -i -e '$a{mark}\\n"
- "{user} ALL=NOPASSWD: /usr/bin/python' "
- "{filename}".format(mark=self.MARK,
- user=self.user,
- script=os.path.realpath(__file__),
- filename=self.SUDOERS))
-
- Command(command, verbose=False).run()
-
- def disable(self):
- """
- Revert sudoers configuration changes
- """
- logging.debug('Restoring sudoers configuration...')
- command = (("sed -i -e '/{mark}/,+1d' "
- "{filename}")
- .format(mark=self.MARK,
- filename=self.SUDOERS))
- Command(command, verbose=False).run()
-
-
-class AutoStartFile(object):
- """
- Generate autostart file contents and write it to proper location
- """
- TEMPLATE = """
-[Desktop Entry]
-Name={pm_operation} test
-Comment=Verify {pm_operation} works properly
-Exec=sudo /usr/bin/python {script} -r {repetitions} -w {wakeup} --hardware-delay {hardware_delay} --pm-delay {pm_delay} --min-pm-time {min_pm_time} --max-pm-time {max_pm_time} --append --total {total} --start {start} --pm-timestamp {pm_timestamp} {silent} --log-level={log_level} --log-dir={log_dir} {pm_operation}
-Type=Application
-X-GNOME-Autostart-enabled=true
-Hidden=false
-"""
-
- def __init__(self, args, user=None):
- self.args = args
- self.user = user
-
- # Generate desktop filename
- # based on environment variables
- username = self.user
- default_config_directory = os.path.expanduser('~{0}/.config'
- .format(username))
- config_directory = os.getenv('XDG_CONFIG_HOME',
- default_config_directory)
- autostart_directory = os.path.join(config_directory, 'autostart')
- if not os.path.exists(autostart_directory):
- os.makedirs(autostart_directory)
-
- basename = '{0}.desktop'.format(os.path.basename(__file__))
- self.desktop_filename = os.path.join(autostart_directory,
- basename)
-
- def write(self):
- """
- Write autostart file to execute the script on startup
- """
- logging.debug('Writing desktop file ({0!r})...'
- .format(self.desktop_filename))
-
- contents = (self.TEMPLATE
- .format(script=os.path.realpath(__file__),
- repetitions=self.args.repetitions - 1,
- wakeup=self.args.wakeup,
- hardware_delay=self.args.hardware_delay,
- pm_delay=self.args.pm_delay,
- min_pm_time=self.args.min_pm_time,
- max_pm_time=self.args.max_pm_time,
- total=self.args.total,
- start=self.args.start,
- pm_timestamp=int(time()),
- silent='--silent' if self.args.silent else '',
- log_level=self.args.log_level_str,
- log_dir=self.args.log_dir,
- pm_operation=self.args.pm_operation))
- logging.debug(contents)
-
- with open(self.desktop_filename, 'w') as f:
- f.write(contents)
-
- def remove(self):
- """
- Remove autostart file to avoid executing the script on startup
- """
- if os.path.exists(self.desktop_filename):
- logging.debug('Removing desktop file ({0!r})...'
- .format(self.desktop_filename))
- os.remove(self.desktop_filename)
-
-
-class LoggingConfiguration(object):
- @classmethod
- def set(cls, log_level, log_filename, append):
- """
- Configure a rotating file logger
- """
- logger = logging.getLogger()
- logger.setLevel(logging.DEBUG)
-
- # Log to sys.stderr using log level passed through command line
- if log_level != logging.NOTSET:
- log_handler = logging.StreamHandler()
- formatter = logging.Formatter('%(levelname)-8s %(message)s')
- log_handler.setFormatter(formatter)
- log_handler.setLevel(log_level)
- logger.addHandler(log_handler)
-
- # Log to rotating file using DEBUG log level
- log_handler = logging.handlers.RotatingFileHandler(log_filename,
- mode='a+',
- backupCount=3)
- formatter = logging.Formatter('%(asctime)s %(levelname)-8s '
- '%(message)s')
- log_handler.setFormatter(formatter)
- log_handler.setLevel(logging.DEBUG)
- logger.addHandler(log_handler)
-
- if not append:
- # Create a new log file on every new
- # (i.e. not scheduled) invocation
- log_handler.doRollover()
-
-
-class MyArgumentParser(object):
- """
- Command-line argument parser
- """
- def __init__(self):
- """
- Create parser object
- """
- pm_operations = ('poweroff', 'reboot')
- description = 'Run power management operation as many times as needed'
- epilog = ('Unknown arguments will be passed '
- 'to the underlying command: poweroff or reboot.')
- parser = ArgumentParser(description=description, epilog=epilog)
- parser.add_argument('-r', '--repetitions', type=int, default=1,
- help=('Number of times that the power management '
- 'operation has to be repeated '
- '(%(default)s by default)'))
- parser.add_argument('-w', '--wakeup', type=int, default=60,
- help=('Timeout in seconds for the wakeup alarm '
- '(%(default)s by default). '
- "Note: wakeup alarm won't be scheduled "
- 'for reboot.'))
- parser.add_argument('--min-pm-time', dest='min_pm_time',
- type=int, default=0,
- help=('Minimum time in seconds that '
- 'it should take the power management '
- 'operation each cycle (0 for reboot and '
- 'wakeup time minus two seconds '
- 'for the other power management operations '
- 'by default)'))
- parser.add_argument('--max-pm-time', dest='max_pm_time',
- type=int, default=300,
- help=('Maximum time in seconds '
- 'that it should take '
- 'the power management operation each cycle '
- '(%(default)s by default)'))
- parser.add_argument('--pm-delay', dest='pm_delay',
- type=int, default=5,
- help=('Delay in seconds '
- 'after hardware information '
- 'has been gathered and before executing '
- 'the power management operation '
- '(%(default)s by default)'))
- parser.add_argument('--hardware-delay', dest='hardware_delay',
- type=int, default=30,
- help=('Delay in seconds before gathering hardware '
- 'information (%(default)s by default)'))
- parser.add_argument('--silent', action='store_true',
- help=("Don't display any dialog "
- 'when test is complete '
- 'to let the script be used '
- 'in automated tests'))
- log_levels = ['notset', 'debug', 'info',
- 'warning', 'error', 'critical']
- parser.add_argument('--log-level', dest='log_level_str',
- default='info', choices=log_levels,
- help=('Log level. '
- 'One of {0} or {1} (%(default)s by default)'
- .format(', '.join(log_levels[:-1]),
- log_levels[-1])))
- parser.add_argument('--log-dir', dest='log_dir', default='/var/log',
- help=('Path to the directory to store log files'))
- parser.add_argument('pm_operation', choices=pm_operations,
- help=('Power management operation to be performed '
- '(one of {0} or {1!r})'
- .format(', '.join(map(repr,
- pm_operations[:-1])),
- pm_operations[-1])))
-
- # Test timestamps
- parser.add_argument('--start', type=int, default=0, help=SUPPRESS)
- parser.add_argument('--pm-timestamp', dest='pm_timestamp',
- type=int, default=0, help=SUPPRESS)
-
- # Append to log on subsequent startups
- parser.add_argument('--append', action='store_true',
- default=False, help=SUPPRESS)
-
- # Total number of iterations initially passed through the command line
- parser.add_argument('--total', type=int, default=0, help=SUPPRESS)
- self.parser = parser
-
- def parse(self):
- """
- Parse command-line arguments
- """
- args, extra_args = self.parser.parse_known_args()
- args.log_level = getattr(logging, args.log_level_str.upper())
-
- # Total number of repetitions
- # is the number of repetitions passed through the command line
- # the first time the script is executed
- if not args.total:
- args.total = args.repetitions
-
- # Test start time automatically set on first iteration
- if not args.start:
- args.start = int(time())
-
- # Wakeup time set to 0 for 'reboot'
- # since wakeup alarm won't be scheduled
- if args.pm_operation == 'reboot':
- args.wakeup = 0
- args.min_pm_time = 0
-
- # Minimum time for each power management operation
- # is set to the wakeup time
- if not args.min_pm_time:
- min_pm_time = args.wakeup - 2
- if min_pm_time < 0:
- min_pm_time = 0
- args.min_pm_time = min_pm_time
-
- # Log filename shows clearly the type of test (pm_operation)
- # and the times it was repeated (repetitions)
- args.log_filename = os.path.join(args.log_dir,
- ('{0}.{1}.{2}.log'
- .format(os.path.basename(__file__),
- args.pm_operation,
- args.total)))
- return args, extra_args
-
-
-if __name__ == '__main__':
- os.environ["LANGUAGE"] = "C"
- sys.exit(main())
diff --git a/jobs/misc/misc-generic.txt b/jobs/misc/misc-generic.txt
index 8e75beb..35a570e 100644
--- a/jobs/misc/misc-generic.txt
+++ b/jobs/misc/misc-generic.txt
@@ -9,34 +9,3 @@ id: misc/generic/sources-list/trusty-oem
command: sources_test /etc/apt/sources.list.d/trusty-oem.list "^deb http://oem.archive.canonical.com/updates/ .* public,^deb-src http://oem.archive.canonical.com/updates/ .* public"
_description:
Check if oem sources list under source.list.d contains correct repository
-
-plugin: shell
-id: misc/generic/stress/reboot
-requires:
- pkg.name == 'upstart'
- pkg.name == 'fwts'
-command: pm_test_misc -r 100 --silent --log-level=notset reboot
-user: root
-description:
- Stress reboot system (100 cycles)
-
-plugin: attachment
-id: misc/generic/stress/reboot_log
-depends: misc/generic/stress/reboot
-command: tar cvfz stress_reboot.tgz $CHECKBOX_DATA/*reboot.100.log && cat $CHECKBOX_DATA/stress_reboot.tgz
-
-plugin: shell
-id: misc/generic/stress/poweroff
-requires:
- pkg.name == 'upstart'
- pkg.name == 'fwts'
-command: pm_test_misc -r 100 --silent --log-level=notset poweroff
-user: root
-description:
- Stress poweroff system (100 cycles)
-
-plugin: attachment
-id: misc/generic/stress/poweroff_log
-depends: misc/generic/stress/poweroff
-command: tar cvfz stress_poweroff.tgz $CHECKBOX_DATA/*poweroff.100.log && cat $CHECKBOX_DATA/stress_poweroff.tgz
-
diff --git a/jobs/somerville/somerville.txt.in b/jobs/somerville/somerville.txt.in
index 60c7c72..375db7f 100644
--- a/jobs/somerville/somerville.txt.in
+++ b/jobs/somerville/somerville.txt.in
@@ -110,116 +110,6 @@ _description:
2. In Step 2 and 3, Dell specific settings ('dell_lin') should appear in the search page link.
3. The web page should refresh to http://www.yahoo.com/?fr=fptb-dell_lin
-plugin: shell
-id: somerville/01-suspend-30
-requires:
- pkg.name == 'pm-utils'
- pkg.name == 'fwts'
-command: pm.py --silent --log-level=notset -r 30 suspend
-user: root
-timeout: 50000
-_description:
- Stress suspend/resume system (30 cycles)
- .
- Log will be available at: /var/log/pm.py.suspend.30.log
-
-plugin: attachment
-id: somerville/02-suspend-30_log
-command: file=/var/log/pm.py.suspend.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/03-hibernate-30
-requires:
- pkg.name == 'pm-utils'
- pkg.name == 'fwts'
-command: pm.py --silent --log-level=notset -r 30 hibernate
-user: root
-timeout: 50000
-_description:
- Stress hibernate/restore system (30 cycles)
- .
- Log will be available at: /var/log/pm.py.hibernate.30.log
-
-plugin: attachment
-id: somerville/04-hibernate-30_log
-command: file=/var/log/pm.py.hibernate.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/05-reboot-30
-requires:
- pkg.name == 'upstart'
- pkg.name == 'fwts'
-command: pm_test -r 30 --log-level=notset reboot
-user: root
-_description:
- Stress reboot system (30 cycles)
- .
- Log will be available at: /var/log/pm.py.reboot.30.log
-
-plugin: attachment
-id: somerville/06-reboot-30_log
-command: file=/var/log/pm_test.reboot.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/07-poweroff-30
-requires:
- pkg.name == 'upstart'
- pkg.name == 'fwts'
-command: pm_test -r 30 --log-level=notset poweroff
-user: root
-_description:
- Stress poweroff system (30 cycles)
- .
- Log will be available at: /var/log/pm.py.poweroff.30.log
-
-plugin: attachment
-id: somerville/08-poweroff-30_log
-command: file=/var/log/pm_test.poweroff.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/09-suspend-30_check
-depends: somerville/01-suspend-30
-command: pm_check.py --log-level=notset /var/log/pm.py.suspend.30.log
-_description: Check logs for the stress suspend/resume (30 cycles) test case
-
-plugin: attachment
-id: somerville/10-suspend-30_check_log
-command:
- file=$CHECKBOX_DATA/pm_check.py.suspend.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/11-hibernate-30_check
-depends: somerville/03-hibernate-30
-command: pm_check.py --log-level=notset /var/log/pm.py.hibernate.30.log
-_description: Check logs for the stress suspend/resume (30 cycles) test case
-
-plugin: attachment
-id: somerville/12-hibernate-30_check_log
-command:
- file=$CHECKBOX_DATA/pm_check.py.hibernate.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/13-reboot-30_check
-depends: somerville/05-reboot-30
-command: pm_check.py --log-level=notset /var/log/pm.py.reboot.30.log
-_description: Check logs for the stress reboot (30 cycles) test case
-
-plugin: attachment
-id: somerville/14-reboot-30_check_log
-command:
- file=$CHECKBOX_DATA/pm_check.py.reboot.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
-plugin: shell
-id: somerville/15-poweroff-30_check
-depends: somerville/07-poweroff-30
-command: pm_check.py --log-level=notset /var/log/pm.py.poweroff.30.log
-_description: Check logs for the stress poweroff (30 cycles) test case
-
-plugin: attachment
-id: somerville/16-poweroff-30_check_log
-command:
- file=$CHECKBOX_DATA/pm_check.py.poweroff.30.log; if [ -e "$file" ]; then cat "$file"; fi
-
plugin: manual
id: somerville/Serial-Port-onboard
_description:
diff --git a/whitelists/sutton-stress.whitelist b/whitelists/sutton-stress.whitelist
index 5bb4965..dfde56e 100644
--- a/whitelists/sutton-stress.whitelist
+++ b/whitelists/sutton-stress.whitelist
@@ -144,7 +144,6 @@
misc
misc/generic
-#misc/generic/stress/.*
#Info attachment jobs
2013.com.canonical.certification::__info__