Home | History | Annotate | Download | only in platform_AddPrinter
      1 # Copyright 2017 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dbus
      6 import logging
      7 import os
      8 from threading import Thread
      9 
     10 from autotest_lib.client.bin import test, utils
     11 from autotest_lib.client.common_lib import file_utils
     12 from autotest_lib.client.common_lib import error
     13 from autotest_lib.client.common_lib.cros import dbus_send
     14 from autotest_lib.client.cros import debugd_util
     15 from fake_printer import FakePrinter
     16 
     17 _FAKE_SERVER_JOIN_TIMEOUT = 10
     18 _FAKE_PRINTER_ID = 'FakePrinterID'
     19 
     20 # Values are from platform/system_api/dbus/debugd/dbus-constants.h.
     21 _CUPS_SUCCESS = 0
     22 
     23 class platform_AddPrinter(test.test):
     24     """
     25     Chrome is brought up, and a cups printer that requires the epson
     26     driver to be downloaded as a component is configured.  The test verifies
     27     that the component is downloaded and a subsequent print command works.
     28     """
     29     version = 1
     30 
     31     def initialize(self, ppd_file):
     32         """
     33         Args:
     34         @param ppd_file: ppd file name
     35         """
     36 
     37         # Set file path.
     38         current_dir = os.path.dirname(os.path.realpath(__file__))
     39         self.pdf_path = os.path.join(current_dir,
     40                            'to_print.pdf')
     41         self.printing_log_path = '/tmp/printing_request.log'
     42 
     43         # Download ppd files
     44         self.ppd_file = '/tmp/%s' % ppd_file
     45         file_utils.download_file(
     46             'https://storage.googleapis.com/chromiumos-test-assets-public'
     47             '/platform_AddPrinter/%s' % ppd_file,
     48             self.ppd_file);
     49 
     50         # Start fake printer.
     51         printer = FakePrinter()
     52         self.server_thread = Thread(target = printer.start,
     53                                args = (self.printing_log_path, ))
     54         self.server_thread.start();
     55 
     56     def cleanup(self):
     57         """
     58         Delete downloaded ppd file, fake printer log file, component (if
     59         downloaded);
     60         """
     61         # Remove component.
     62         if hasattr(self, 'component'):
     63           self.delete_component(self.component)
     64 
     65         # Remove temp files.
     66         if os.path.exists(self.ppd_file):
     67           os.remove(self.ppd_file)
     68         if os.path.exists(self.printing_log_path):
     69           os.remove(self.printing_log_path)
     70 
     71     def load_ppd(self, ppd_path):
     72         """
     73         Returns the contents of a file as a dbus.ByteArray.
     74 
     75         @param file_name: The path of the file.
     76 
     77         """
     78         with open(ppd_path, 'rb') as f:
     79             content = dbus.ByteArray(f.read())
     80             return content
     81 
     82     def add_a_printer(self, ppd_path):
     83         """
     84         Add a printer manually given ppd file.
     85 
     86         Args:
     87         @param ppd_path: path to ppd file
     88 
     89         @raises: error.TestFail if could not setup a printer
     90         """
     91         logging.info('add printer from ppd:' + ppd_path);
     92 
     93         ppd_contents = self.load_ppd(ppd_path)
     94         result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
     95                                      _FAKE_PRINTER_ID, 'socket://127.0.0.1/',
     96                                                       ppd_contents)
     97         if result != _CUPS_SUCCESS:
     98             raise error.TestFail('valid_config - Could not setup valid '
     99                 'printer %d' % result)
    100 
    101     def print_a_page(self, golden_file_path):
    102         """
    103         Print a page and check print request output
    104 
    105         Args:
    106         @param golden_file_path: path to printing request golden file.
    107 
    108         @raises: error.TestFail if printing request generated cannot be
    109         verified.
    110         """
    111         # Check if CUPS is running.
    112         printers = utils.system_output('lpstat -t')
    113         logging.info(printers)
    114 
    115         # Issue print request.
    116         utils.system_output(
    117             'lp -d %s %s' %
    118             (_FAKE_PRINTER_ID, self.pdf_path)
    119         );
    120 
    121         self.server_thread.join(_FAKE_SERVER_JOIN_TIMEOUT)
    122         if self.server_thread.isAlive():
    123           raise error.TestFail('ERROR: Server never terminated')
    124 
    125         if not os.path.isfile(self.printing_log_path):
    126           raise error.TestFail('ERROR: File never written')
    127 
    128         # Verify print request with a golden file.
    129         output = utils.system_output(
    130             'cmp', ignore_status=True, retain_output=True,
    131             args=(self.printing_log_path, golden_file_path)
    132         )
    133         if output:
    134             raise error.TestFail('ERROR: Printing request is not verified!')
    135         logging.info('cmp output:' + output);
    136 
    137 
    138     def delete_component(self, component):
    139         """
    140         Delete filter component via dbus API
    141 
    142         Args:
    143         @param component: name of component
    144         """
    145         logging.info('delete component:' + component);
    146 
    147         dbus_send.dbus_send(
    148             'org.chromium.ComponentUpdaterService',
    149             'org.chromium.ComponentUpdaterService',
    150             '/org/chromium/ComponentUpdaterService',
    151             'UnloadComponent',
    152             timeout_seconds=20,
    153             user='root',
    154             args=[dbus.String(component)])
    155 
    156     def download_component(self, component):
    157         """
    158         Download filter component via dbus API
    159 
    160         Args:
    161         @param component: name of component
    162 
    163         @raises: error.TestFail is component is not loaded.
    164         """
    165         logging.info('download component:' + component);
    166 
    167         res = dbus_send.dbus_send(
    168             'org.chromium.ComponentUpdaterService',
    169             'org.chromium.ComponentUpdaterService',
    170             '/org/chromium/ComponentUpdaterService',
    171             'LoadComponent',
    172             timeout_seconds=20,
    173             user='root',
    174             args=[dbus.String(component)])
    175 
    176         if res.response == '':
    177           raise error.TestFail('Component could not be loaded.')
    178 
    179     def run_once(self, golden_file, component=None):
    180         """
    181         Args:
    182         @param golden_file: printing request golden file name
    183         """
    184         if component:
    185             self.component = component
    186             self.download_component(self.component)
    187 
    188         current_dir = os.path.dirname(os.path.realpath(__file__))
    189         self.add_a_printer(self.ppd_file)
    190         self.print_a_page(os.path.join(current_dir, golden_file));
    191