blob: 8bd0a5edbda00bc6d0d47f45da4e74adbaace967 [file] [log] [blame]
# 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 tempfile
import thread
import gobject
import gtk
from gtk import gdk
import serial_task
import region_task
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error, utils
from autotest_lib.client.cros import factory
from autotest_lib.client.cros.factory import shopfloor
from autotest_lib.client.cros.factory import ui as ful
_MESSAGE_PREPARE_VPD = "Preparing VPD..."
class factory_VPD(test.test):
version = 2
def write_vpd(self, vpd):
"""Writes a VPD structure into system.
@param vpd: A dictionary with 'ro' and 'rw' keys, each associated with a
key-value VPD data set.
"""
def shell(command):
factory.log(command)
utils.system(command)
def format_vpd_parameter(vpd_dict):
"""Formats a key-value dictionary into VPD syntax."""
# Writes in sorted ordering so the VPD structure will be more
# deterministic.
return ' '.join(('-s "%s"="%s"' % (key, vpd_dict[key])
for key in sorted(vpd_dict)))
VPD_LIST = (('RO_VPD', 'ro'), ('RW_VPD', 'rw'))
with tempfile.NamedTemporaryFile() as temp_file:
name = temp_file.name
for (section, vpd_type) in VPD_LIST:
if not vpd.get(vpd_type, None):
continue
parameter = format_vpd_parameter(vpd[vpd_type])
shell('vpd -i %s %s' % (section, parameter))
def worker_thread(self, vpd):
"""Task thread for writing VPD."""
def update_label(text):
with ful.gtk_lock:
self.label.set_text(text)
if vpd is None:
update_label("Fetching VPD information...")
vpd = shopfloor.get_vpd()
# Flatten key-values in VPD dictionary.
vpd_list = []
for vpd_type in ('ro', 'rw'):
vpd_list += ['%s: %s = %s' % (vpd_type, key, vpd[vpd_type][key])
for key in sorted(vpd[vpd_type])]
update_label("Writing VPD:\n%s" % '\n'.join(vpd_list))
self.write_vpd(vpd)
def run_shop_floor(self):
"""Runs with shop floor system."""
self.label = ful.make_label(_MESSAGE_PREPARE_VPD)
thread.start_new_thread(self.worker_thread, (None, ))
ful.run_test_widget(self.job, self.label)
def stop_task(self, task):
factory.log("Stopping task: %s" % task.__class__.__name__)
self.tasks.remove(task)
self.find_next_task()
def find_next_task(self):
if self.tasks:
task = self.tasks[0]
factory.log("Starting task: %s" % task.__class__.__name__)
task.start(self.window, self.container, self.stop_task)
else:
# No more tasks - try to write into VPD.
self.label = ful.make_label(_MESSAGE_PREPARE_VPD)
self.container.add(self.label)
self.container.show_all()
thread.start_new_thread(self.worker_thread, (self.vpd, ))
def run_interactively(self):
"""Runs interactively (without shop floor system)."""
def register_window(window):
self.window = window
self.find_next_task()
return True
self.vpd = {'ro': {}, 'rw': {}}
self.container = gtk.VBox()
self.tasks = [serial_task.SerialNumberTask(self.vpd),
region_task.SelectRegionTask(self.vpd)]
ful.run_test_widget(self.job, self.container,
window_registration_callback=register_window)
def run_once(self):
factory.log('%s run_once' % self.__class__)
gtk.gdk.threads_init()
if shopfloor.is_enabled():
self.run_shop_floor()
else:
self.run_interactively()
factory.log('%s run_once finished' % repr(self.__class__))