• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import dbus
6import logging
7import os
8from threading import Thread
9
10from autotest_lib.client.bin import test, utils
11from autotest_lib.client.common_lib import file_utils
12from autotest_lib.client.common_lib import error
13from autotest_lib.client.common_lib.cros import dbus_send
14from autotest_lib.client.cros import debugd_util
15from 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
23class 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