blob: 7dc8a4307f3d72ac293961287db81eaf4a0f7c3d [file] [log] [blame]
# Copyright 2016 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.
"""A factory test to test the function of display.
The test will display images on the display.
It will extract image files from factory/misc/display_images.tar.gz by default.
User can add new xx.tar.gz in the private overlay.
The display order is based on the sorted file name.
Two directories, dut/ and station/, are required in the image archive xx.tar.gz.
For each image to be tested, two images with same file name are required in each
directory, but we can use different extension name depending on the file format.
The image under dut/ is for displaying on DUT. The image under station/ is for
providing information to operators.
e.g.
dut/abc.ppm and station/abc.bmp
"""
import glob
import logging
import os
import factory_common # pylint: disable=unused-import
from cros.factory.device import device_utils
from cros.factory.test.i18n import _
from cros.factory.test.i18n import arg_utils as i18n_arg_utils
from cros.factory.test import test_case
from cros.factory.test import test_ui
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import file_utils
from cros.factory.utils import process_utils
_IMAGE_ROOT = '/usr/local/factory/misc/'
_DEFAULT_IMAGE_FILE = 'display_images.tar.gz'
_IMAGE_DIR = 'images'
_STATION_IMAGE_DIR = 'station'
_DUT_IMAGE_DIR = 'dut'
class DisplayImageTest(test_case.TestCase):
"""Tests the function of display by displaying images.
Properties:
_extract_dir: temp directory for keeping image files on the station.
_station_image_urls: list of image paths for displaying on Station.
_dut_temp_dir: temp directory for keeping image files on DUT.
_image_index: index of the image to be displayed.
_uploaded_index: index of the latest uploaded image.
_total_images: number of total images.
_can_pass: check if operator checks all images.
"""
ARGS = [
i18n_arg_utils.I18nArg(
'title', 'Label Title of the test', default=_('Display Test')),
Arg('compressed_image_file', str, 'Compressed image file name.',
default=_DEFAULT_IMAGE_FILE)
]
def setUp(self):
"""Initializes frontend presentation and properties."""
self._dut = device_utils.CreateDUTInterface()
self.ui.SetHTML(self.args.title, id='display-title')
self._dut_temp_dir = self._dut.temp.mktemp(True, '', 'display')
self._image_index = -1
self._uploaded_index = -1
self._can_pass = False
self._extract_dir = os.path.join(self.ui.GetStaticDirectoryPath(),
_IMAGE_DIR)
file_utils.ExtractFile(
os.path.join(_IMAGE_ROOT, self.args.compressed_image_file),
self._extract_dir)
image_paths = sorted(
glob.glob(os.path.join(self._extract_dir, _DUT_IMAGE_DIR, '*')))
self._dut_image_paths = [
self._dut.path.join(self._dut_temp_dir, os.path.basename(x))
for x in image_paths
]
station_paths = sorted(
glob.glob(os.path.join(self._extract_dir, _STATION_IMAGE_DIR, '*')))
self._station_image_urls = [
os.path.join(_IMAGE_DIR, _STATION_IMAGE_DIR, os.path.basename(x))
for x in station_paths
]
self.assertEqual(
len(image_paths),
len(station_paths),
'There should be same number of images in dut and station folders.')
# Because uploading images cost a lot of time, use another thread to do it.
# Operator can test uploaded images in parallel.
process_utils.StartDaemonThread(
target=self.UploadImages, args=(station_paths, ))
images = ''.join('<img src="%s" class="image-thumb">' % path
for path in self._station_image_urls)
self.ui.SetHTML(images, id='display-table')
def tearDown(self):
self._dut.display.StopDisplayImage()
process_utils.Spawn(['rm', '-rf', self._extract_dir],
check_call=True, log=True)
self._dut.Call(['rm', '-rf', self._dut_temp_dir])
def runTest(self):
"""Sets the callback function of keys and run the test."""
while True:
pressed_key = self.ui.WaitKeysOnce([test_ui.SPACE_KEY, test_ui.ENTER_KEY])
if pressed_key == test_ui.SPACE_KEY:
self.OnSpacePressed()
elif pressed_key == test_ui.ENTER_KEY:
if self._can_pass:
break
def UploadImages(self, image_paths):
"""Upload images to DUT."""
for i in xrange(len(image_paths)):
# path in the station
path = image_paths[i]
dut_path = self._dut_image_paths[i]
name = os.path.basename(path)
self.ui.SetHTML(
_('({index}/{total}) Uploading images {name}',
index=i + 1,
total=len(image_paths),
name=name),
id='upload')
self._dut.link.Push(path, dut_path)
self._uploaded_index = i
self.ui.SetHTML(_('All images uploaded.'), id='upload')
def OnSpacePressed(self):
"""Display next image."""
display_index = (self._image_index + 1) % len(self._station_image_urls)
# Don't do display if the image is not uploaded.
if display_index > self._uploaded_index:
return
# show the image on the chromebook to let operator know what will be shown
# on the DUT.
path = self._station_image_urls[display_index]
tag = '%d: <img src="%s" class="image-info">' % (display_index, path)
self.ui.SetHTML(tag, id='display-image-info')
# Display image on DUT.
dut_path = self._dut_image_paths[display_index]
logging.info('Display image index %d, image %s, dut path %s',
display_index, path, dut_path)
self._dut.display.StopDisplayImage()
self._dut.display.DisplayImage(dut_path)
self._image_index = display_index
if display_index == len(self._station_image_urls) - 1:
self._can_pass = True