blob: d60d9920d1d7b4d68f3db1eec3787964df68ef9f [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os
import sys
import time
import gtk
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import factory_setup_modules
from cros.factory.test import factory
from cros.factory.test import gooftools
from cros.factory.test import shopfloor
from cros.factory.test import task
from cros.factory.test import ui
_MSG_FINALIZING = 'Finalizing, please wait...'
class PreflightTask(task.FactoryTask):
"""Checks if the system is ready for finalization."""
# User interface theme
COLOR_DISABLED = gtk.gdk.Color(0x7000, 0x7000, 0x7000)
COLOR_PASSED = ui.LIGHT_GREEN
COLOR_FAILED = ui.RED
# Messages for localization
MSG_CHECKING = ("Checking system status for finalization...\n"
"正在檢查系統是否已可執行最終程序...")
MSG_PENDING = ("System is NOT ready. Please fix RED tasks and then\n"
" press SPACE to continue,\n"
" or press 'f' to force starting finalization procedure.\n"
"系統尚未就緒。\n"
"請修正紅色項目後按空白鍵重新檢查,\n"
"或是按下 'f' 鍵以強迫開始最終程序。")
MSG_READY = ("System is READY. Press SPACE to start FINALIZATION!\n"
"系統已準備就緒。 請按空白鍵開始最終程序!")
def __init__(self, test_list, developer_mode):
def create_label(message):
return ui.make_label(message, fg=self.COLOR_DISABLED,
alignment=(0, 0.5))
self.updating = False
self.developer_mode = developer_mode
self.test_list = test_list
self.items = [(self.check_required_tests,
create_label("Verify no tests failed\n"
"確認無測試項目失敗"))]
if developer_mode:
return
# Items only enforced in non-developer mode.
self.items += [(self.check_developer_switch,
create_label("Turn off Developer Switch\n"
"停用開發者開關(DevSwitch)")),
(self.check_write_protect,
create_label("Enable write protection pin\n"
"確認硬體寫入保護已開啟"))]
def check_developer_switch(self):
""" Checks if developer switch button is disabled """
try:
gooftools.run('gooftool verify_switch_dev')
except:
return False
return True
def check_write_protect(self):
""" Checks if hardware write protection pin is enabled """
try:
gooftools.run('gooftool verify_switch_wp')
except:
return False
return True
def check_required_tests(self):
""" Checks if all previous tests are passed """
state_map = self.test_list.get_state_map()
return not any(x.status == factory.TestState.FAILED
for x in state_map.values())
def update_results(self):
self.updating = True
for _, label in self.items:
label.modify_fg(gtk.STATE_NORMAL, self.COLOR_DISABLED)
self.label_status.set_label(self.MSG_CHECKING)
def update_summary():
self.updating = False
self.label_status.set_label(
self.MSG_READY if all(self.results) else self.MSG_PENDING)
# In developer mode, provide more visual feedback.
if self.developer_mode:
time.sleep(.5)
def next_test():
if not items:
update_summary()
return
checker, label = items.pop(0)
result = checker()
label.modify_fg(gtk.STATE_NORMAL,
self.COLOR_PASSED if result else self.COLOR_FAILED)
self.results.append(result)
task.schedule(next_test)
# Perform all tests
items = self.items[:]
self.results = []
task.schedule(next_test)
def window_key_press(self, widget, event):
if self.updating:
return True
if event.keyval == ord('f'):
factory.log("WARNING: Operator manually forced finalization.")
elif event.keyval == ord(' '):
if not all(self.results):
self.update_results()
return True
else:
return False
self.stop()
return True
def start(self):
self.results = [False]
# Build main window.
self.label_status = ui.make_label('', fg=ui.WHITE)
vbox = gtk.VBox()
vbox.set_spacing(20)
vbox.pack_start(self.label_status, False, False)
for _, label in self.items:
vbox.pack_start(label, False, False)
self.widget = vbox
self.add_widget(self.widget)
task.schedule(self.update_results)
self.connect_window('key-press-event', self.window_key_press)
class FinalizeTask(task.FactoryTask):
def __init__(self, developer_mode, secure_wipe, upload_method):
self.developer_mode = developer_mode
self.secure_wipe = secure_wipe
self.upload_method = upload_method
def alert(self, message, times=3):
"""Alerts user that a required test is bypassed."""
for i in range(times, 0, -1):
factory.log(('WARNING: Factory Finalize: %s. ' +
'THIS DEVICE CANNOT BE QUALIFIED. ' +
'(continue in %d seconds)') % (message, i))
time.sleep(1)
def normalize_upload_method(self, original_method):
"""Build the report file name and solve variables."""
method = original_method
if method in [None, 'none']:
# gooftool accepts only 'none', not empty string.
return 'none'
if method == 'shopfloor':
method = 'shopfloor:%s#%s' % (shopfloor.get_server_url(),
shopfloor.get_serial_number())
factory.log('norm_upload_method: %s -> %s' % (original_method, method))
return method
def start(self):
self.add_widget(ui.make_label(_MSG_FINALIZING))
task.schedule(self.do_finalize)
def do_finalize(self):
upload_method = self.normalize_upload_method(self.upload_method)
command = 'gooftool -v 4 -l %s finalize' % factory.CONSOLE_LOG_PATH
if self.developer_mode:
self.alert('DEVELOPER MODE ENABLED')
command += ' --dev'
if not self.secure_wipe:
command += ' --fast'
command += ' --upload_method "%s"' % upload_method
gooftools.run(command)
# TODO(hungte) Use Reboot in test list to replace this, or add a
# key-press check in developer mode.
os.system("sync; sync; sync; shutdown -r now")
self.stop()
class factory_Finalize(test.test):
version = 3
def run_once(self,
developer_mode=False,
secure_wipe=False,
upload_method='none',
test_list_path=None):
factory.log('%s run_once' % self.__class__)
test_list = factory.read_test_list(test_list_path)
self.tasks = [PreflightTask(test_list, developer_mode),
FinalizeTask(developer_mode, secure_wipe, upload_method)]
task.run_factory_tasks(self.job, self.tasks)
factory.log('%s run_once finished' % repr(self.__class__))