debugd: Add tests for CupsTool operations.

Test CupsAddManuallyConfiguredPrinter and CupsAddAutoConfiguredPrinter
to verify that they return the correct error codes.

BUG=chromium:683241,chromium:683254
TEST=test_that ... e:platform_DebugDaemonCupsAdd.*
CQ-DEPEND=CL:452804

Change-Id: I3d9c45a7a599070a8d5c61a31f40d055e31720d1
Reviewed-on: https://chromium-review.googlesource.com/452546
Commit-Ready: Sean Kau <[email protected]>
Tested-by: Sean Kau <[email protected]>
Reviewed-by: Katherine Threlkeld <[email protected]>
Reviewed-by: Sean Kau <[email protected]>
diff --git a/client/cros/debugd_util.py b/client/cros/debugd_util.py
new file mode 100644
index 0000000..0b6c682
--- /dev/null
+++ b/client/cros/debugd_util.py
@@ -0,0 +1,12 @@
+# Copyright 2017 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 dbus
+
+
+def iface():
+  """Returns the interface object for debugd."""
+  bus = dbus.SystemBus()
+  proxy = bus.get_object('org.chromium.debugd', '/org/chromium/debugd')
+  return dbus.Interface(proxy, dbus_interface='org.chromium.debugd')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.autoconf b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.autoconf
new file mode 100644
index 0000000..60baaba
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.autoconf
@@ -0,0 +1,29 @@
+# Copyright 2017 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.
+
+AUTHOR = "[email protected]"
+NAME = "platform_DebugDaemonCupsAddPrinters"
+PURPOSE = "Verify that debugd's Cups* functions behave properly."
+
+ATTRIBUTES = "suite:bvt-perbuild"
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+JOB_RETRIES = 2
+
+CRITERIA = """
+This test fails if the incorrect error is reported for a Cups
+autoconfiguration failure.
+"""
+
+DOC = """
+Exercises the debugd CupsAddAutoConfiguredPrinter method.
+
+Verifies that the error code is correct for an unreachable printer.
+"""
+
+job.run_test('platform_DebugDaemonCupsAddPrinters',
+             situation='autoconf',
+             tags='autoconf')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.lpadmin b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.lpadmin
new file mode 100644
index 0000000..2bec56b
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.lpadmin
@@ -0,0 +1,28 @@
+# Copyright 2017 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.
+
+AUTHOR = "[email protected]"
+NAME = "platform_DebugDaemonCupsAddPrinters"
+PURPOSE = "Verify that debugd's Cups* functions behave properly."
+
+ATTRIBUTES = "suite:bvt-perbuild"
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+JOB_RETRIES = 2
+
+CRITERIA = """
+This test will fail if debugd stops reporting lpadmin failures.
+"""
+
+DOC = """
+Exercises the debugd CupsAddManuallyConfigured Printer operation.
+
+Verifies that failures of the lpadmin tool are correctly reported
+back to the caller of the Debug Daemon.
+"""
+
+job.run_test('platform_DebugDaemonCupsAddPrinters',
+             situation='lpadmin', tag='lpadmin')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.ppd_error b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.ppd_error
new file mode 100644
index 0000000..66385a4
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.ppd_error
@@ -0,0 +1,27 @@
+# Copyright 2017 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.
+
+AUTHOR = "[email protected]"
+NAME = "platform_DebugDaemonCupsAddPrinters"
+PURPOSE = "Verify that debugd's Cups* functions behave properly."
+
+ATTRIBUTES = "suite:bvt-perbuild"
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+JOB_RETRIES = 2
+
+CRITERIA = """
+This test fails if we cannot reject invalid PPDs.
+"""
+
+DOC = """
+Exercises the debugd CupsAddManuallyConfigured Printer operation.
+
+Verifies that invalid PPDs are rejected with the correct error code.
+"""
+
+job.run_test('platform_DebugDaemonCupsAddPrinters',
+             situation='ppd_error', tag='ppd_error')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.valid_config b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.valid_config
new file mode 100644
index 0000000..23979c0
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/control.valid_config
@@ -0,0 +1,27 @@
+# Copyright 2017 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.
+
+AUTHOR = "[email protected]"
+NAME = "platform_DebugDaemonCupsAddPrinters"
+PURPOSE = "Verify that debugd's Cups* functions behave properly."
+
+ATTRIBUTES = "suite:bvt-perbuild"
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+JOB_RETRIES = 2
+
+CRITERIA = """
+This test fails if we can not add printers to CUPS through debugd.
+"""
+
+DOC = """
+Exercises the debugd CupsAddManuallyConfigured Printer operation.
+
+Verifies that we can add a printer with a valid PPD to CUPS.
+"""
+
+job.run_test('platform_DebugDaemonCupsAddPrinters',
+             situation='valid_config', tag='valid_config')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/platform_DebugDaemonCupsAddPrinters.py b/client/site_tests/platform_DebugDaemonCupsAddPrinters/platform_DebugDaemonCupsAddPrinters.py
new file mode 100644
index 0000000..b70f24b
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/platform_DebugDaemonCupsAddPrinters.py
@@ -0,0 +1,141 @@
+# Copyright 2017 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 dbus
+
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.cros import debugd_util
+
+_GENERIC_PPD = 'GenericPostScript.ppd.gz'
+
+# Values are from platform/system_api/dbus/debugd/dbus-constants.h.
+_CUPS_SUCCESS = 0
+_CUPS_INVALID_PPD_ERROR = 2
+_CUPS_LPADMIN_ERROR = 3
+_CUPS_AUTOCONF_FAILURE = 4
+
+
+class platform_DebugDaemonCupsAddPrinters(test.test):
+    """
+    Exercise CupsAddManuallyConfiguredPrinter from debugd.
+
+    Exercise the various add printer conditions and verify that the
+    error codes are correct.
+
+    """
+    version = 1
+
+    def load_ppd(self, file_name):
+        """
+        Returns the contents of a file as a dbus.ByteArray.
+
+        @param file_name: The name of the file.
+
+        """
+        abs_path = '%s/%s' % (self.srcdir, file_name)
+        with open(abs_path, 'rb') as f:
+            content = dbus.ByteArray(f.read())
+        return content
+
+    def test_autoconf(self):
+        """
+        Attempt to add an unreachable autoconfigured printer.
+
+        Verifies that upon autoconf failure, the error code is
+        CUPS_AUTOCONF_FAILURE.
+
+        @raises TestFail: If the test failed.
+
+        """
+        autoconfig_result = debugd_util.iface().CupsAddAutoConfiguredPrinter(
+                            'AutoconfPrinter', 'ipp://127.0.0.1/ipp/print')
+        # There's no printer at this address.  Autoconf failure expected.
+        # CUPS_AUTOCONF_FAILURE.
+        if autoconfig_result != _CUPS_AUTOCONF_FAILURE:
+            raise error.TestFail('Incorrect error code received: %i' %
+                                 autoconfig_result)
+
+    def test_ppd_error(self):
+        """
+        Validates that malformed PPDs are rejected.
+
+        The expected error code is CUPS_INVALID_PPD error.
+
+        @raises TestFail: If the test failed.
+
+        """
+        ppd_contents = dbus.ByteArray('This is not a valid ppd')
+        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
+                'ManualPrinterBreaks', 'socket://127.0.0.1/ipp/fake_printer',
+                ppd_contents)
+        # PPD is invalid.  Expect a CUPS_INVALID_PPD error.
+        if result != _CUPS_INVALID_PPD_ERROR:
+            raise error.TestFail('Incorrect error code received %d' % result)
+
+    def test_valid_config(self):
+        """
+        Validates that a printer can be installed.
+
+        Verifies that given a valid configuration and a well formed PPD,
+        DebugDaemon reports a CUPS_SUCCESS error code indicating
+        success.
+
+        @raises TestFail: If the result from debugd was not CUPS_SUCCESS.
+
+        """
+        ppd_contents = self.load_ppd(_GENERIC_PPD)
+        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
+                 'ManualPrinterGood', 'socket://127.0.0.1/ipp/fake_printer',
+                 ppd_contents)
+        # PPD is valid.  Printer doesn't need to be reachable.  This is
+        # expected to pass with CUPS_SUCCESS.
+        if result != _CUPS_SUCCESS:
+            raise error.TestFail('Could not setup valid printer %d' % result)
+
+    def test_lpadmin(self):
+        """
+        Verify the error for a failure in lpadmin.
+
+        The failure is reported as CUPS_LPADMIN_FAILURE.
+
+        @raises TestFail: If the error code from debugd is incorrect.
+
+        """
+        ppd_contents = self.load_ppd(_GENERIC_PPD)
+        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
+                 'CUPS rejects names with spaces',
+                 'socket://127.0.0.1/ipp/fake_printer',
+                 ppd_contents)
+        if result != _CUPS_LPADMIN_ERROR:
+            raise error.TestFail(
+                'Names with spaces should be rejected by CUPS %d' % result)
+
+        result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
+                 'UnrecognizedProtocol',
+                 'badbadbad://127.0.0.1/ipp/fake_printer',
+                  ppd_contents)
+        if result != _CUPS_LPADMIN_ERROR:
+            raise error.TestFail(
+                  'Unrecognized protocols should be rejected by CUPS. %d' %
+                  result)
+
+    def run_once(self, situation):
+        """
+        Runs tests based on the designated situation.
+
+        @raises TestError: If an unrecognized situation was used.
+
+        """
+        if situation == 'valid_config':
+            self.test_valid_config()
+        elif situation == 'lpadmin':
+            self.test_lpadmin()
+        elif situation == 'ppd_error':
+            self.test_ppd_error()
+        elif situation == 'autoconf':
+            self.test_autoconf()
+        else:
+            raise error.TestError('situation must be autoconf, valid_config, '
+                                  'lpadmin, or ppd_error')
diff --git a/client/site_tests/platform_DebugDaemonCupsAddPrinters/src/GenericPostScript.ppd.gz b/client/site_tests/platform_DebugDaemonCupsAddPrinters/src/GenericPostScript.ppd.gz
new file mode 100644
index 0000000..4a362c0
--- /dev/null
+++ b/client/site_tests/platform_DebugDaemonCupsAddPrinters/src/GenericPostScript.ppd.gz
Binary files differ