Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: saft_utility.py

Issue 6881019: Fix SAFT to work on all x86 platforms using crossystem. (Closed) Base URL: ssh://gitrw.chromium.org:9222/saft.git@master
Patch Set: Fix another Mario recovery reason shortcoming. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chromeos_interface.py ('k') | test_chromeos_interface.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 '''Test utility for verifying ChromeOS firmware.''' 6 '''Test utility for verifying ChromeOS firmware.'''
7 7
8 import datetime 8 import datetime
9 import functools 9 import functools
10 import getopt 10 import getopt
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 STEP_FILE = 'fw_test_step' # The next test step number. 90 STEP_FILE = 'fw_test_step' # The next test step number.
91 FW_BACKUP_FILE = 'flashrom.bak' # Preserved original flashrom contents. 91 FW_BACKUP_FILE = 'flashrom.bak' # Preserved original flashrom contents.
92 FW_COPY_FILE = 'flashrom.new' # A copy of the flashrom contents being tested. 92 FW_COPY_FILE = 'flashrom.new' # A copy of the flashrom contents being tested.
93 FWID_BACKUP_FILE = 'fwid.bak' # FWID reported by the original firmware. 93 FWID_BACKUP_FILE = 'fwid.bak' # FWID reported by the original firmware.
94 FWID_NEW_FILE = 'fwid.new' # FWID reported by the firmware being tested. 94 FWID_NEW_FILE = 'fwid.new' # FWID reported by the firmware being tested.
95 95
96 BASE_STORAGE_DEVICE = '/dev/sda' 96 BASE_STORAGE_DEVICE = '/dev/sda'
97 97
98 # The list of shell executables necessary for this program to work. 98 # The list of shell executables necessary for this program to work.
99 REQUIRED_PROGRAMS = ''' 99 REQUIRED_PROGRAMS = '''
100 cgpt blkid flashrom reboot_mode readlink rootdev vbutil_firmware vbutil_kernel 100 cgpt crossystem blkid flashrom readlink rootdev vbutil_firmware vbutil_kernel
101 mosys 101 mosys
102 ''' 102 '''
103 103
104 104
105 FLASHROM_HANDLER = flashrom_handler.FlashromHandler() 105 FLASHROM_HANDLER = flashrom_handler.FlashromHandler()
106 CHROS_IF = chromeos_interface.ChromeOSInterface(__name__ != '__main__') 106 CHROS_IF = chromeos_interface.ChromeOSInterface(__name__ != '__main__')
107 cgpt_st = cgpt_state.CgptState('COMPLETE', CHROS_IF, BASE_STORAGE_DEVICE) 107 cgpt_st = cgpt_state.CgptState('COMPLETE', CHROS_IF, BASE_STORAGE_DEVICE)
108 108
109 def allow_multiple_section_input(image_operator): 109 def allow_multiple_section_input(image_operator):
110 @functools.wraps(image_operator) 110 @functools.wraps(image_operator)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 self.window = None 168 self.window = None
169 self.tpm_handler = None 169 self.tpm_handler = None
170 170
171 def _verify_fw_id(self, compare_to_file): 171 def _verify_fw_id(self, compare_to_file):
172 '''Verify if the current firmware ID matches the contents a file. 172 '''Verify if the current firmware ID matches the contents a file.
173 173
174 compare_to_file - a string, name of the file in the state directory. 174 compare_to_file - a string, name of the file in the state directory.
175 ''' 175 '''
176 old_fwid = open( 176 old_fwid = open(
177 self.chros_if.state_dir_file(compare_to_file), 'r').read() 177 self.chros_if.state_dir_file(compare_to_file), 'r').read()
178 now_fwid = open(self.chros_if.acpi_file('FWID'), 'r').read() 178 now_fwid = self.chros_if.cs.fwid
179 return old_fwid == now_fwid 179 return old_fwid == now_fwid
180 180
181 def _get_step(self): 181 def _get_step(self):
182 '''Set the current value of SAFT step number.''' 182 '''Set the current value of SAFT step number.'''
183 step_file = self.chros_if.state_dir_file(STEP_FILE) 183 step_file = self.chros_if.state_dir_file(STEP_FILE)
184 step = open(step_file, 'r').read().strip() 184 step = open(step_file, 'r').read().strip()
185 return int(step) 185 return int(step)
186 186
187 def _set_step(self, step): 187 def _set_step(self, step):
188 '''Set the SAFT step number to control the next test pass.''' 188 '''Set the SAFT step number to control the next test pass.'''
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 245
246 os.rmdir(tmp_dir) 246 os.rmdir(tmp_dir)
247 247
248 def _check_runtime_env(self): 248 def _check_runtime_env(self):
249 '''Ensure that the script is running in proper environment. 249 '''Ensure that the script is running in proper environment.
250 250
251 This involves checking that the script is running off a removable 251 This involves checking that the script is running off a removable
252 device, configuring proper file names for logging, etc. 252 device, configuring proper file names for logging, etc.
253 ''' 253 '''
254 line = self.chros_if.run_shell_command_get_output( 254 line = self.chros_if.run_shell_command_get_output(
255 'df %s' % self.mydir)[-1] 255 'df %s' % self.mydir)[1]
256 256
257 self.base_partition = line.split()[0] 257 self.base_partition = line.split()[0]
258 if self.base_partition == '/dev/root': 258 if self.base_partition == '/dev/root':
259 self.base_partition = self.chros_if.get_root_dev() 259 self.base_partition = self.chros_if.get_root_dev()
260 260
261 if not self.chros_if.is_removable_device(self.base_partition): 261 if not self.chros_if.is_removable_device(self.base_partition):
262 raise FwError( 262 raise FwError(
263 'This test must run off a removable device, not %s' 263 'This test must run off a removable device, not %s'
264 % self.base_partition) 264 % self.base_partition)
265 265
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if self.kern_handler: 336 if self.kern_handler:
337 vers_a = self.kern_handler.get_version('a') 337 vers_a = self.kern_handler.get_version('a')
338 vers_b = self.kern_handler.get_version('b') 338 vers_b = self.kern_handler.get_version('b')
339 if not self.tpm_handler.kernel_version_good(vers_a, vers_b): 339 if not self.tpm_handler.kernel_version_good(vers_a, vers_b):
340 raise FwError('TPM kernel version mismatch (%d %d %s)' % ( 340 raise FwError('TPM kernel version mismatch (%d %d %s)' % (
341 vers_a, vers_b, self.base_partition)) 341 vers_a, vers_b, self.base_partition))
342 342
343 def set_try_fw_b(self): 343 def set_try_fw_b(self):
344 '''Request running firmware B on the next restart.''' 344 '''Request running firmware B on the next restart.'''
345 self.chros_if.log('Requesting restart with FW B') 345 self.chros_if.log('Requesting restart with FW B')
346 self.chros_if.run_shell_command('reboot_mode --try_firmware_b=1') 346 self.chros_if.cs.fwb_tries = 1
347 347
348 def request_recovery_boot(self): 348 def request_recovery_boot(self):
349 '''Request running in recovery mode on the restart.''' 349 '''Request running in recovery mode on the restart.'''
350 self.chros_if.log('Requesting restart in recovery mode') 350 self.chros_if.log('Requesting restart in recovery mode')
351 self.chros_if.run_shell_command('reboot_mode --recovery=1') 351 self.chros_if.cs.request_recovery()
352
352 353
353 @allow_multiple_section_input 354 @allow_multiple_section_input
354 def restore_firmware(self, section): 355 def restore_firmware(self, section):
355 '''Restore the requested firmware section (previously corrupted).''' 356 '''Restore the requested firmware section (previously corrupted).'''
356 self.chros_if.log('Restoring firmware %s' % section) 357 self.chros_if.log('Restoring firmware %s' % section)
357 FLASHROM_HANDLER.restore_firmware(section) 358 FLASHROM_HANDLER.restore_firmware(section)
358 359
359 @allow_multiple_section_input 360 @allow_multiple_section_input
360 def corrupt_firmware(self, section): 361 def corrupt_firmware(self, section):
361 '''Corrupt the requested firmware section.''' 362 '''Corrupt the requested firmware section.'''
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 datetime.datetime.strftime( 523 datetime.datetime.strftime(
523 datetime.datetime.now(), '%b %d %Y'))) 524 datetime.datetime.now(), '%b %d %Y')))
524 chros_if.log('Original boot state %s' % chros_if.boot_state_vector()) 525 chros_if.log('Original boot state %s' % chros_if.boot_state_vector())
525 self.chros_if = chros_if 526 self.chros_if = chros_if
526 fw_image = opt_dictionary['image_file'] 527 fw_image = opt_dictionary['image_file']
527 self.new_fw_image() 528 self.new_fw_image()
528 FLASHROM_HANDLER.dump_whole( 529 FLASHROM_HANDLER.dump_whole(
529 self.chros_if.state_dir_file(FW_BACKUP_FILE)) 530 self.chros_if.state_dir_file(FW_BACKUP_FILE))
530 self.new_fw_image(fw_image) 531 self.new_fw_image(fw_image)
531 self._handle_saft_script(True) 532 self._handle_saft_script(True)
532 shutil.copyfile(self.chros_if.acpi_file('FWID'), 533 open(self.chros_if.state_dir_file(FWID_BACKUP_FILE), 'w'
533 self.chros_if.state_dir_file(FWID_BACKUP_FILE)) 534 ).write(self.chros_if.cs.fwid)
534 shutil.copyfile(fw_image, self.chros_if.state_dir_file(FW_COPY_FILE)) 535 shutil.copyfile(fw_image, self.chros_if.state_dir_file(FW_COPY_FILE))
535 536
536 self._set_step(0) 537 self._set_step(0)
537 cgpt_st.set_step(0) 538 cgpt_st.set_step(0)
538 539
539 def next_step(self): 540 def next_step(self):
540 '''Function to execute a single SAFT step. 541 '''Function to execute a single SAFT step.
541 542
542 This function is running after each reboot. It determines the current 543 This function is running after each reboot. It determines the current
543 step the SAFT is on, executes the appropriate action, increments the 544 step the SAFT is on, executes the appropriate action, increments the
544 step value and then restats the machine. 545 step value and then restats the machine.
545 ''' 546 '''
546 547
547 this_step = self._get_step() 548 this_step = self._get_step()
548 549
549 # Import when needed, because otherwise running test generates a 550 # Import when needed, because otherwise running test generates a
550 # warning exception about the unavailable display. 551 # warning exception about the unavailable display.
551 window = __import__('window') 552 window = __import__('window')
552 self.window = window.GraphThread() 553 self.window = window.GraphThread()
553 554
554 if this_step == 0: 555 if this_step == 0:
555 shutil.copyfile(self.chros_if.acpi_file('FWID'), 556 open(self.chros_if.state_dir_file(FWID_NEW_FILE), 'w'
556 self.chros_if.state_dir_file(FWID_NEW_FILE)) 557 ).write(self.chros_if.cs.fwid)
557 558
558 if self._verify_fw_id(FWID_BACKUP_FILE): 559 if self._verify_fw_id(FWID_BACKUP_FILE):
559 # we expected FWID to change, but it did not - have the firmware 560 # we expected FWID to change, but it did not - have the firmware
560 # been even replaced? 561 # been even replaced?
561 self.chros_if.log('New firmware - old FWID') 562 self.chros_if.log('New firmware - old FWID')
562 self.finish_saft(False) 563 self.finish_saft(False)
563 test_state_tuple = self.test_state_sequence[this_step] 564 test_state_tuple = self.test_state_sequence[this_step]
564 expected_vector = test_state_tuple[0] 565 expected_vector = test_state_tuple[0]
565 action = test_state_tuple[1] 566 action = test_state_tuple[1]
566 567
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 # Have chros_if.shutdown move the log into the '/var' directory to 635 # Have chros_if.shutdown move the log into the '/var' directory to
635 # make it easier to see SAFT results. 636 # make it easier to see SAFT results.
636 self.chros_if.shut_down(os.path.join('/var', LOG_FILE)) 637 self.chros_if.shut_down(os.path.join('/var', LOG_FILE))
637 638
638 self.window.stop() 639 self.window.stop()
639 sys.exit(0) 640 sys.exit(0)
640 641
641 # Firmware self test instance controlling this module. 642 # Firmware self test instance controlling this module.
642 FST = FirmwareTest() 643 FST = FirmwareTest()
643 644
644 # This is a tuple of tuples controlling the SAFT state machine. The states 645 # This is a tuple of tuples controlling the SAFT state machine. The states are
645 # are expected to be passed strictly in order. The states are identified 646 # expected to be passed strictly in order. The states used to be identified by
646 # by the contents of BINF.[012] files in the sys fs ACPI directory. The 647 # the contents of BINF.[012] files in the sys fs ACPI directory. Now they are
647 # BINF files store information about the reason for reboot, what 648 # derived from the crossystem output to match previously reported states.
648 # firmware/kernel partitions were used, etc.
649 # 649 #
650 # The first element of each component tuple is the expected state of the 650 # The first element of each component tuple is the expected state of the
651 # machine (a ':' concatenation of the BINF files' contents). 651 # machine.
652 # 652 #
653 # The second element of the component tuples is the action to take to 653 # The second element of the component tuples is the action to take to
654 # advance the test. The action is a function to call. The last line has 654 # advance the test. The action is a function to call. The last line has
655 # action set to None, which indicates to the state machine that the test 655 # action set to None, which indicates to the state machine that the test
656 # is over. 656 # is over.
657 # 657 #
658 # The third component, if present, is the parameter to pass to the action 658 # The third component, if present, is the parameter to pass to the action
659 # function. 659 # function.
660 660
661 TEST_STATE_SEQUENCE = ( 661 TEST_STATE_SEQUENCE = (
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 if 'next_step' in opt_dictionary: 768 if 'next_step' in opt_dictionary:
769 if len(opt_dictionary) != 1: 769 if len(opt_dictionary) != 1:
770 usage('--next_step (when specified) must be the only parameter', 1) 770 usage('--next_step (when specified) must be the only parameter', 1)
771 try: 771 try:
772 FST.next_step() 772 FST.next_step()
773 except SystemExit: 773 except SystemExit:
774 pass # No real exception, this is just an exit (for whatever 774 pass # No real exception, this is just an exit (for whatever
775 # reason), gtk window already closed. 775 # reason), gtk window already closed.
776 except: 776 except:
777 # Whatever error that might be, gtk window must be shut. 777 # Whatever error that might be, gtk window must be shut.
778 FST.window.stop() 778 if FST.window:
779 FST.window.stop()
779 780
780 # Make sure exception information is saved in the log. 781 # Make sure exception information is saved in the log.
781 exc_type, exc_info, exc_trace = sys.exc_info() 782 exc_type, exc_info, exc_trace = sys.exc_info()
782 print 'exception type:', str(exc_type) 783 print 'exception type:', str(exc_type)
783 print 'exception info:', str(exc_info) 784 print 'exception info:', str(exc_info)
784 traceback.print_tb(exc_trace) 785 traceback.print_tb(exc_trace)
785 sys.exit(0) 786 sys.exit(0)
786 787
787 # check if all executables are available 788 # check if all executables are available
788 missing_execs = [] 789 missing_execs = []
(...skipping 30 matching lines...) Expand all
819 main(sys.argv) 820 main(sys.argv)
820 except (getopt.GetoptError, ImportError): 821 except (getopt.GetoptError, ImportError):
821 usage(sys.exc_info()[1], 1) 822 usage(sys.exc_info()[1], 1)
822 except (FwError, flashrom_handler.FlashromHandlerError): 823 except (FwError, flashrom_handler.FlashromHandlerError):
823 MSG = 'Error: %s' % str(sys.exc_info()[1]) 824 MSG = 'Error: %s' % str(sys.exc_info()[1])
824 print MSG 825 print MSG
825 CHROS_IF.log(MSG) 826 CHROS_IF.log(MSG)
826 sys.exit(1) 827 sys.exit(1)
827 828
828 sys.exit(0) 829 sys.exit(0)
OLDNEW
« no previous file with comments | « chromeos_interface.py ('k') | test_chromeos_interface.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698