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
6
7from autotest_lib.client.bin import test
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros import cups
10from autotest_lib.client.cros import debugd_util
11
12_GENERIC_PPD = 'GenericPostScript.ppd.gz'
13
14# Values are from platform/system_api/dbus/debugd/dbus-constants.h.
15_CUPS_SUCCESS = 0
16_CUPS_INVALID_PPD_ERROR = 2
17_CUPS_LPADMIN_ERROR = 3
18_CUPS_AUTOCONF_FAILURE = 4
19
20
21class platform_DebugDaemonCupsAddPrinters(test.test):
22    """
23    Exercise CupsAddManuallyConfiguredPrinter from debugd.
24
25    Exercise the various add printer conditions and verify that the
26    error codes are correct.
27
28    """
29    version = 1
30
31    def load_ppd(self, file_name):
32        """
33        Returns the contents of a file as a dbus.ByteArray.
34
35        @param file_name: The name of the file.
36
37        """
38        abs_path = '%s/%s' % (self.srcdir, file_name)
39        with open(abs_path, 'rb') as f:
40            content = dbus.ByteArray(f.read())
41        return content
42
43    def test_autoconf(self):
44        """
45        Attempt to add an unreachable autoconfigured printer.
46
47        Verifies that upon autoconf failure, the error code is
48        CUPS_AUTOCONF_FAILURE.
49
50        @raises TestFail: If the test failed.
51
52        """
53        autoconfig_result = debugd_util.iface().CupsAddAutoConfiguredPrinter(
54                            'AutoconfPrinter', 'ipp://127.0.0.1/ipp/print')
55        # There's no printer at this address.  Autoconf failure expected.
56        # CUPS_AUTOCONF_FAILURE.
57        if autoconfig_result != _CUPS_AUTOCONF_FAILURE:
58            raise error.TestFail('autoconf - Incorrect error code received: '
59                '%i' % autoconfig_result)
60
61    def test_ppd_error(self):
62        """
63        Validates that malformed PPDs are rejected.
64
65        The expected error code is CUPS_INVALID_PPD error.
66
67        @raises TestFail: If the test failed.
68
69        """
70        ppd_contents = dbus.ByteArray('This is not a valid ppd')
71        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
72                'ManualPrinterBreaks', 'socket://127.0.0.1/ipp/fake_printer',
73                ppd_contents)
74        # PPD is invalid.  Expect a CUPS_INVALID_PPD error.
75        if result != _CUPS_INVALID_PPD_ERROR:
76            raise error.TestFail('ppd_error - Incorrect error code received '
77                '%d' % result)
78
79    def test_valid_config(self):
80        """
81        Validates that a printer can be installed.
82
83        Verifies that given a valid configuration and a well formed PPD,
84        DebugDaemon reports a CUPS_SUCCESS error code indicating
85        success.
86
87        @raises TestFail: If the result from debugd was not CUPS_SUCCESS.
88
89        """
90        ppd_contents = self.load_ppd(_GENERIC_PPD)
91        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
92                 'ManualPrinterGood', 'socket://127.0.0.1/ipp/fake_printer',
93                 ppd_contents)
94        # PPD is valid.  Printer doesn't need to be reachable.  This is
95        # expected to pass with CUPS_SUCCESS.
96        if result != _CUPS_SUCCESS:
97            raise error.TestFail('valid_config - Could not setup valid '
98                'printer %d' % result)
99
100    def test_lpadmin(self):
101        """
102        Verify the error for a failure in lpadmin.
103
104        The failure is reported as CUPS_LPADMIN_FAILURE.
105
106        @raises TestFail: If the error code from debugd is incorrect.
107
108        """
109        ppd_contents = self.load_ppd(_GENERIC_PPD)
110        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
111                 'CUPS rejects names with spaces',
112                 'socket://127.0.0.1/ipp/fake_printer',
113                 ppd_contents)
114        if result != _CUPS_LPADMIN_ERROR:
115            raise error.TestFail(
116                'lpadmin - Names with spaces should be rejected by CUPS '
117                '%d' % result)
118
119        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
120                 'UnrecognizedProtocol',
121                 'badbadbad://127.0.0.1/ipp/fake_printer',
122                  ppd_contents)
123        if result != _CUPS_LPADMIN_ERROR:
124            raise error.TestFail(
125                  'lpadmin - Unrecognized protocols should be rejected by '
126                  'CUPS. %d' %
127                  result)
128
129    def run_once(self):
130        """
131        Runs tests based on the designated situation.
132
133        @raises TestError: If an unrecognized situation was used.
134
135        """
136        # Exits test if platform does not have CUPS
137        cups.has_cups_or_die()
138
139        self.test_valid_config()
140        self.test_lpadmin()
141        self.test_ppd_error()
142        self.test_autoconf()
143