| Index: client/site_tests/suite_Factory/control
|
| diff --git a/client/site_tests/suite_Factory/control b/client/site_tests/suite_Factory/control
|
| index d038a431bf59030a0ee33b37ce64b2867f5c2401..64e7f777e136db3d5ceaf3145e4e2a9bd13ba870 100644
|
| --- a/client/site_tests/suite_Factory/control
|
| +++ b/client/site_tests/suite_Factory/control
|
| @@ -24,30 +24,25 @@ control process). """
|
|
|
|
|
| import imp
|
| -import subprocess
|
| -import sys
|
| -import time
|
| -
|
| imp.load_source('common', job.autodir + '/bin/common.py')
|
| from autotest_lib.client.bin import factory
|
| from autotest_lib.client.bin import utils
|
|
|
|
|
| -# -- CUSTOMIZATION --------------------------------------------------
|
| -# You can tune these settings to fit your factory process.
|
| -
|
| -# change this to False if you want and allow fast wipe (insecure)
|
| -DO_FACTORY_SECURE_WIPE = True
|
| -
|
| -# -- END OF CUSTOMIZATION ------------------------------------------
|
| -
|
| -
|
| -_RESULTS_PATH = job.autodir + '/results/default'
|
| -_STATUS_FILE_PATH = _RESULTS_PATH + '/status'
|
| -_FACTORY_UI_PATH = job.autodir + '/bin/factory_ui'
|
| +# These definitions are expose these classes directly into this
|
| +# namespace, so that the following exec'ed file can have cleaner
|
| +# syntax. These are done in this fashion, as opposed to "from factory
|
| +# import <class>" to work-around Python namespace wackiness -- the
|
| +# from syntax does not work, creating new classes.
|
| +OperatorTest = factory.OperatorTest
|
| +InformationScreen = factory.InformationScreen
|
| +AutomatedSequence = factory.AutomatedSequence
|
| +AutomatedSubTest = factory.AutomatedSubTest
|
| +AutomatedRebootSubTest = factory.AutomatedRebootSubTest
|
|
|
|
|
| -_REBOOT_SEQ_ITERATIONS = 2
|
| +# This exec defines TEST_LIST in global scope.
|
| +execfile(job.autodir + '/site_tests/suite_Factory/test_list')
|
|
|
|
|
| # Hack to work around autotest's obsession with GRUB.
|
| @@ -55,336 +50,46 @@ job.bootloader.set_default = lambda x: None
|
| job.bootloader.boot_once = lambda x: None
|
|
|
|
|
| -# TEST ORDERING: Tests in the test_list will be run in the order
|
| -# below, unless the operator interrupts the flow via keyboard
|
| -# shortcut. To cause immediate execution of the run-in tests, for
|
| -# example, reorder runin to occur as the first test in the test_list.
|
| -
|
| -test_list = [
|
| - factory.TestData(
|
| - label_en='start',
|
| - label_zw='開始',
|
| - formal_name='factory_Dummy',
|
| - trigger='e',
|
| - dargs={'quit_key':ord(' '),
|
| - 'msg':'Hit SPACE to start testing...\n按 "空白鍵" 開始測試...'}),
|
| - factory.TestData(
|
| - label_en='sync',
|
| - label_zw='同步',
|
| - formal_name='factory_ScriptWrapper',
|
| - trigger='s',
|
| - dargs={'cmdline': job.autodir +
|
| - '/site_tests/factory_ScriptWrapper/dummy.sh'}),
|
| - factory.TestData(
|
| - label_en='run-in',
|
| - label_zw='燒機測試',
|
| - formal_name='step_runin',
|
| - automated_seq=[
|
| - # Match HWQual ID by running hardware_Components with ignored cids.
|
| - factory.TestData(
|
| - label_en='hwqual id matching',
|
| - label_zw='型號匹配',
|
| - formal_name='hardware_Components',
|
| - dargs={'approved_dbs':'qualified_components*',
|
| - 'ignored_cids':[
|
| - 'hash_ro_firmware',
|
| - 'part_id_hwqual',
|
| - 'vendor_id_bios',
|
| - 'version_rw_firmware',
|
| - ]}),
|
| - factory.TestData(
|
| - label_en='gpio switch check',
|
| - label_zw='檢查 gpio 開關',
|
| - formal_name='hardware_GPIOSwitches'),
|
| - factory.TestData(
|
| - label_en='system stress',
|
| - label_zw='壓力測試',
|
| - formal_name='hardware_SAT',
|
| - dargs={'seconds': 60}),
|
| - factory.TestData(
|
| - label_en='graphics',
|
| - label_zw='圖型',
|
| - formal_name='graphics_GLBench'),
|
| - factory.TestData(
|
| - label_en='reboot (%s times)' % _REBOOT_SEQ_ITERATIONS,
|
| - label_zw='重新開機 (%s 次)' % _REBOOT_SEQ_ITERATIONS,
|
| - formal_name='factory_RebootStub')],
|
| - trigger='r'),
|
| - factory.TestData(
|
| - label_en='keyboard',
|
| - label_zw='鍵盤',
|
| - formal_name='factory_Keyboard',
|
| - trigger='k',
|
| - dargs={'layout':'en_us'}),
|
| - factory.TestData(
|
| - label_en='touchpad',
|
| - label_zw='觸控板',
|
| - formal_name='factory_Touchpad',
|
| - trigger='t'),
|
| - factory.TestData(
|
| - label_en='leds',
|
| - label_zw='機身側燈',
|
| - formal_name='factory_Leds',
|
| - trigger='l',
|
| - dargs={'led_ctl_path':
|
| - '/usr/local/autotest/site_tests/factory_Leds/src/ec_ctl'}),
|
| - factory.TestData(
|
| - label_en='display',
|
| - label_zw='顯示',
|
| - formal_name='factory_Display',
|
| - trigger='m'),
|
| - factory.TestData(
|
| - label_en='ExtDisplay',
|
| - label_zw='外接顯示',
|
| - formal_name='factory_ExtDisplay',
|
| - trigger='n',
|
| - dargs={'has_audio':True,
|
| - 'sample':'deps/factory/fhorn.wav'}),
|
| - factory.TestData(
|
| - label_en='camera',
|
| - label_zw='相機',
|
| - formal_name='factory_Camera',
|
| - trigger='c'),
|
| - factory.TestData(
|
| - label_en='audio',
|
| - label_zw='音源裝置',
|
| - formal_name='factory_Audio',
|
| - trigger='a',
|
| - dargs={'sample':'deps/factory/fhorn.wav'}),
|
| - factory.TestData(
|
| - label_en='usb',
|
| - formal_name='factory_ExternalStorage',
|
| - trigger='u',
|
| - dargs={'media':'USB'}),
|
| - factory.TestData(
|
| - label_en='sd',
|
| - formal_name='factory_ExternalStorage',
|
| - trigger='d',
|
| - dargs={'media':'SD'}),
|
| - factory.TestData(
|
| - label_en='bluetooth',
|
| - label_zw='藍芽',
|
| - formal_name='factory_Dummy',
|
| - trigger='o',
|
| - dargs={'msg':'bluetooth test, one day...'}),
|
| - factory.TestData(
|
| - label_en='3g',
|
| - label_zw='3G上網',
|
| - formal_name='factory_Dummy',
|
| - trigger='g',
|
| - dargs={'msg':'3g test, one day...'}),
|
| - factory.TestData(
|
| - label_en='wifi',
|
| - label_zw='無線上網',
|
| - formal_name='factory_Dummy',
|
| - trigger='w',
|
| - dargs={'msg':'wifi test, one day...'}),
|
| - factory.TestData(
|
| - label_en='light sensor',
|
| - label_zw='光传感器',
|
| - formal_name='factory_LightSensor',
|
| - dargs={'lux_max':1000, 'lux_min':1},
|
| - trigger='i'),
|
| -
|
| - # THIS IS A GOOGLE REQUIRED TEST.
|
| - # PLEASE DO NOT REMOVE THIS TEST IN PRODUCTION RELEASES.
|
| - factory.TestData(
|
| - label_en='devrec',
|
| - label_zw='還原模式',
|
| - formal_name='factory_DeveloperRecovery',
|
| - trigger='b',
|
| - dargs={'layout':'devrec'}),
|
| -
|
| - # THIS IS A GOOGLE REQUIRED TEST.
|
| - # PLEASE DO NOT REMOVE THIS TEST IN PRODUCTION RELEASES.
|
| - factory.TestData(
|
| - label_en='final',
|
| - label_zw='最後測試',
|
| - formal_name='step_final_stage1',
|
| - automated_seq=[
|
| - # THIS IS A GOOGLE REQUIRED TEST.
|
| - # PLEASE DO NOT REMOVE THIS TEST IN PRODUCTION RELEASES.
|
| - factory.TestData(
|
| - label_en='write GBB',
|
| - label_zw='寫入GBB',
|
| - formal_name='factory_WriteGBB'),
|
| - factory.TestData(
|
| - label_en='reboot',
|
| - label_zw='重新開機',
|
| - formal_name='factory_RebootStub'),
|
| - factory.TestData(
|
| - label_en='component validation',
|
| - label_zw='元件驗證',
|
| - formal_name='hardware_Components')],
|
| - trigger='f'),
|
| -
|
| - # THIS IS A GOOGLE REQUIRED TEST.
|
| - # PLEASE DO NOT REMOVE THIS TEST IN PRODUCTION DEVICES.
|
| - factory.TestData(
|
| - label_en='wipe',
|
| - label_zw='清除',
|
| - formal_name='factory_Wipe',
|
| - trigger='x',
|
| - dargs={'secure_wipe':DO_FACTORY_SECURE_WIPE,
|
| - 'write_protect':False,
|
| - 'msg':('hit TAB+ENTER to write protect FW and '
|
| - 'wipe test image!...\n'
|
| - '請按下 TAB+ENTER 啟用寫入保護以及清除'
|
| - '測試程式資料!...')}),
|
| - # NOTE: factory_Wipe.dargs support following variables for temporary
|
| - # testing. You can add these settings to help internal test, but
|
| - # THESE ARE GOOGLE REQUIRED TESTS SO YOU SHOULD NOT DISABLE THEM
|
| - # IN PRODUCTION RELEASES.
|
| - # - check_developer_switch: check for developer button switch
|
| - # - write_protect: enable and check flash ROM write protection
|
| - # TODO(hungte) Although the 'write_protect' should be a Google required
|
| - # test, we decide to disable it until first official release of
|
| - # Chrome OS. Please remove that line for the real release.
|
| -
|
| - factory.TestData(
|
| - label_en='review',
|
| - label_zw='報告',
|
| - formal_name='factory_Review',
|
| - repeat_forever=True,
|
| - trigger='z'),
|
| -]
|
| -
|
| -for test in test_list:
|
| - test.tag_prefix = test.trigger
|
| - for subtest in test.automated_seq:
|
| - subtest.tag_prefix = test.formal_name
|
| -
|
| -test_map = factory.make_test_map(test_list)
|
| -trigger_set = factory.make_trigger_set(test_list)
|
| -
|
| -
|
| -def run_subtest(name, dargs_map):
|
| - job.run_test(name, **dargs_map[name])
|
| -
|
| -
|
| -def step_reboot_seq(dargs_map, i=0):
|
| - if i < _REBOOT_SEQ_ITERATIONS:
|
| - job.next_step_prepend([step_reboot_seq, dargs_map, i + 1])
|
| - factory.log('rebooting (iteration %d)' % i)
|
| - time.sleep(5)
|
| +def step_reboot_seq(tag_prefix, total_iterations, i=0):
|
| + if i < total_iterations:
|
| + job.next_step_prepend([step_reboot_seq, tag_prefix,
|
| + total_iterations, i + 1])
|
| + factory.log('rebooting (iteration %d of %d)' % (i, total_iterations))
|
| job.reboot()
|
| else:
|
| - run_subtest('factory_RebootStub', dargs_map)
|
| - step_init()
|
| -
|
| -
|
| -hwqual_id = None
|
| + step_init(intentional_reboot_subtest_tag_prefix=tag_prefix)
|
|
|
| -def get_hwqual_id():
|
| - # TODO: Move HWQual ID to StatusMap.
|
| - global hwqual_id
|
| - if not hwqual_id:
|
| - hwqual_id = find_hwqual_id()
|
| - return hwqual_id
|
| -
|
| -def find_hwqual_id():
|
| - cmd = ('find %s -name keyval | xargs grep -h ^hwqual_id= | '
|
| - 'sed s/hwqual_id=// | head -1' %
|
| - (_RESULTS_PATH + '/hardware_Components.step_runin_*'))
|
| - hwqual_id = utils.system_output(cmd).strip()
|
| - hwqual_id = hwqual_id.rsplit(' ', 1)[0].replace(' ', '_')
|
| - if not hwqual_id:
|
| - factory.log('fail to get the HWQual ID')
|
| - return hwqual_id
|
| -
|
| -
|
| -def update_dargs(test, dargs_map, update_map):
|
| - for (key, value) in update_map.iteritems():
|
| - dargs_map[test][key] = value
|
| -
|
| -
|
| -def step_runin(ui, dargs_map):
|
| - run_subtest('hardware_Components', dargs_map)
|
| - run_subtest('hardware_GPIOSwitches', dargs_map)
|
| - job.drop_caches_between_iterations = True
|
| - run_subtest('hardware_SAT', dargs_map)
|
| - job.drop_caches_between_iterations = False
|
| - run_subtest('graphics_GLBench', dargs_map)
|
| - step_reboot_seq(dargs_map)
|
| -
|
| -
|
| -def step_final_stage1(ui, dargs_map):
|
| - update_dargs('factory_WriteGBB', dargs_map,
|
| - {'gbb_file': 'gbb_*%s' % get_hwqual_id()})
|
| - run_subtest('factory_WriteGBB', dargs_map)
|
| - job.next_step_prepend([step_final_stage2, ui, dargs_map])
|
| - factory.log('rebooting')
|
| - time.sleep(5)
|
| - job.reboot()
|
| -
|
| -
|
| -def step_final_stage2(ui, dargs_map):
|
| - run_subtest('factory_RebootStub', dargs_map)
|
| - update_dargs('hardware_Components', dargs_map,
|
| - {'approved_dbs': 'qualified_components_*%s' % get_hwqual_id()})
|
| - run_subtest('hardware_Components', dargs_map)
|
| - step_init()
|
| -
|
| -
|
| -def step_init():
|
| - '''Launch the factory UI, which will then make decisions on which
|
| - tests to run in which order. This is to support user driven
|
| - out-of-order test execution based on keyboard shortcuts.
|
| -
|
| - For each test, a trigger (possibly None) is communicated to the
|
| - UI, which then replies with the test name and a count number that
|
| - becomes the autotest tag to allow repeated test execution while
|
| - preserving logs.
|
| -
|
| - When the tests themselves run, they are expected to look for
|
| - (using the factory_test library) keyboard events that match test
|
| - switching triggers. When a trigger happens, it should be written
|
| - to the factory.RESULT_FILE_PATH, which will be read after the test
|
| - completed and the result comminicated onwards to the UI.'''
|
|
|
| +def step_init(intentional_reboot_subtest_tag_prefix=None):
|
| job.next_step([step_init])
|
|
|
| - ui = factory.UiClient(_FACTORY_UI_PATH)
|
| -
|
| - ui.send(test_list)
|
| - ui.send(_STATUS_FILE_PATH)
|
| + factory_ui_path = job.autodir + '/bin/factory_ui'
|
| + status_file_path = job.autodir + '/results/default/status'
|
|
|
| - test_widget_size = ui.recv()
|
| - factory.log('received test_widget_size = %s' % repr(test_widget_size))
|
| + status_map = factory.StatusMap(TEST_LIST, status_file_path)
|
| + ui = factory.UiClient(TEST_LIST, factory_ui_path, status_file_path)
|
| + control_state = factory.ControlState(job, TEST_LIST, ui, status_map,
|
| + status_file_path)
|
|
|
| - ui.send_cmd_next_test()
|
| - test, test_count = ui.recv_target_test_update(test_map)
|
| + if intentional_reboot_subtest_tag_prefix:
|
| + reboot_subtest = status_map.test_db.get_subtest_by_tag_prefix(
|
| + intentional_reboot_subtest_tag_prefix)
|
| + control_state.run_test(reboot_subtest)
|
| + status_map.read_new_data()
|
|
|
| + test = status_map.next_untested()
|
| while test is not None:
|
| - if test.automated_seq:
|
| - tag = '%s_%s' % (test.formal_name, test_count)
|
| - dargs_map = dict((st.formal_name, st.dargs)
|
| - for st in test.automated_seq)
|
| - for i in dargs_map:
|
| - dargs_map[i].update(tag=tag)
|
| - exec('%s(ui, dargs_map)' % (test.formal_name))
|
| - result = None
|
| + if isinstance(test, factory.AutomatedSequence):
|
| + for subtest in test.subtest_list:
|
| + if isinstance(subtest, factory.AutomatedRebootSubTest):
|
| + tag_prefix = status_map.test_db.get_tag_prefix(subtest)
|
| + step_reboot_seq(tag_prefix, subtest.iterations)
|
| + else:
|
| + control_state.run_test(subtest)
|
| + if control_state.activated_kbd_shortcut_test:
|
| + break
|
| else:
|
| - dargs = test.dargs
|
| - dargs.update({
|
| - 'tag': '%s_%s' % (test.tag_prefix, test_count),
|
| - 'test_tag_prefix': test.tag_prefix,
|
| - 'test_count': test_count,
|
| - 'test_widget_size': test_widget_size,
|
| - 'trigger_set': trigger_set,
|
| - 'status_file_path' : _STATUS_FILE_PATH,
|
| - 'test_list': test_list})
|
| - with open(factory.RESULT_FILE_PATH, 'w') as file:
|
| - file.write('None\n')
|
| - job.run_test(test.formal_name, **dargs)
|
| - with open(factory.RESULT_FILE_PATH, 'r') as file:
|
| - result = eval(file.readline())
|
| -
|
| - if result is not None:
|
| - ui.send_cmd_switch_to(result)
|
| - else:
|
| - ui.send_cmd_next_test()
|
| -
|
| - test, test_count = ui.recv_target_test_update(test_map)
|
| -
|
| - factory.log('factory testing completed')
|
| + control_state.run_test(test)
|
| + status_map.read_new_data()
|
| + test = (control_state.activated_kbd_shortcut_test or
|
| + status_map.next_untested())
|
|
|