Example #1
0
 def test_bad_base_case_value(self):
     """
     Verify that transforming a string to a numeric value will raise an
     exception.
     """
     with self.assertRaises(IntoDPUnexpectedValueError):
         xformer("x")(["string"])
Example #2
0
 def test_variant_depth(self):
     """
     Verify that a nested variant has appropriate variant depth.
     """
     self.assertEqual(
         xformer('v')([('v', ('v', ('b', False)))])[0].variant_level, 3)
     self.assertEqual(
         xformer('v')([('v', ('ab', [False]))])[0],
         dbus.Array([dbus.Boolean(False)], signature='b', variant_level=2))
     self.assertEqual(
         xformer('av')([([('v', ('b', False))])])[0],
         dbus.Array([dbus.Boolean(False, variant_level=2)], signature="v"))
Example #3
0
    def test_unpacking(self, value):
        """
        Test that signature unpacking works.
        """
        dbus_value = xformer("v")([value])[0]
        unpacked = signature(dbus_value, unpack=True)
        packed = signature(dbus_value)

        self.assertEqual(packed, "v")
        self.assertFalse(unpacked.startswith("v"))
Example #4
0
    def test_exceptions(self, sig):
        """
        Test that an exception is raised for a dict if '{' is blacklisted.

        Need to also blacklist 'b' and 's', since dbus.String and dbus.Boolean
        constructors can both convert a dict.
        """

        xform = xformer(sig)

        with self.assertRaises(IntoDPUnexpectedValueError):
            xform([{True: True}])
def _xformers(key_to_sig):
    """
    Get a map from keys to functions from a map of names to signatures.

    :param key_to_sig: a map from keys to signatures
    :type key_to_sig: dict of object * str
    :returns: a map from keys to functions
    :rtype: dict of object * xformation function
    """
    sig_to_xformers = \
       dict((sig, xformer(sig)) for (_, sig) in key_to_sig.values())
    return dict((method, (names, sig_to_xformers[sig])) for \
       (method, (names, sig)) in key_to_sig.items())
Example #6
0
    def test_struct(self, strat):
        """
        Test exception throwing on a struct signature when number of items
        is not equal to number of complete types in struct signature.
        """
        (sig, struct) = strat

        xform = xformer(sig)

        with self.assertRaises(IntoDPUnexpectedValueError):
            xform([struct + (1,)])

        with self.assertRaises(IntoDPUnexpectedValueError):
            xform([struct[:-1]])
    def testParsing(self, a_signature):
        """
        Test that parsing is always succesful.

        Verify that the original signature corresponds to the signature
        returned by the parser and to the signature of the generated value.

        Verify that the variant levels always descend within the constructed
        value, always by single steps and that leaves of the value always
        have variant level of 0 or 1.
        """
        base_type_objects = [
           x.example() for x in \
              STRATEGY_GENERATOR.parseString(a_signature, parseAll=True)
        ]
        results = self._PARSER.PARSER.parseString(a_signature, parseAll=True)
        funcs = [f for (f, _) in results]
        sigs = [s for (_, s) in results]

        results = [f(x) for (f, x) in zip(funcs, base_type_objects)]
        values = [v for (v, _) in results]
        levels = [l for (_, l) in results]

        for sig_orig, (sig_synth, (level, value)) in \
           zip(dbus.Signature(a_signature), zip(sigs, zip(levels, values))):
            self.assertEqual(sig_orig, sig_synth)
            if 'v' not in sig_orig:
                self.assertEqual(level, 0)
            self.assertIsNotNone(_descending(value))
            self.assertEqual(signature(value), sig_orig)

        pairs = \
           zip(
              dbus.Signature(a_signature),
              xformer(a_signature)(base_type_objects)
           )
        # test equality of signatures, rather than results, since nan != nan
        for sig, value in pairs:
            self.assertEqual(sig, signature(value))
Example #8
0
 def test_variant_depth(self):
     """
     Verify that a nested variant has appropriate variant depth.
     """
     self.assertEqual(
         xformer("v")([("v", ("v", ("b", False)))])[0],
         dbus.Boolean(False, variant_level=3),
     )
     self.assertEqual(
         xformer("v")([("v", ("ab", [False]))])[0],
         dbus.Array([dbus.Boolean(False)], signature="b", variant_level=2),
     )
     self.assertEqual(
         xformer("av")([([("v", ("b", False))])])[0],
         dbus.Array([dbus.Boolean(False, variant_level=2)], signature="v"),
     )
     self.assertEqual(
         xformer("a{bv}")([{
             True: ("b", False)
         }])[0],
         dbus.Dictionary(
             {dbus.Boolean(True): dbus.Boolean(False, variant_level=1)}),
     )
     self.assertEqual(
         xformer("(bv)")([(True, ("b", False))])[0],
         dbus.Struct(
             [dbus.Boolean(True),
              dbus.Boolean(False, variant_level=1)]),
     )
     self.assertEqual(
         xformer("(bv)")([(True, ("v", ("b", True)))])[0],
         dbus.Struct(
             [dbus.Boolean(True),
              dbus.Boolean(True, variant_level=2)],
             signature="bv",
             variant_level=0,
         ),
     )
Example #9
0
 def test_bad_struct_value(self):
     """
     Verify that transforming a dict when a struct is expected fails.
     """
     with self.assertRaises(IntoDPUnexpectedValueError):
         xformer("(qq)")({})
Example #10
0
 def test_bad_array_value(self):
     """
     Verify that passing a dict for an array will raise an exception.
     """
     with self.assertRaises(IntoDPUnexpectedValueError):
         xformer("a(qq)")([{}])
    def build_method(name, inargs):
        """
        Build a method for this class.

        :param str name: the name of the method
        :param inargs: the in-arguments to this methods
        :type inargs: iterable of Element
        """
        try:
            arg_names = [e.attrib["name"] for e in inargs]
        except KeyError as err:  # pragma: no cover
            fmt_str = (
                "No name attribute found for some argument for method "
                '"%s" belonging to interface "%s"'
            )
            raise DPClientGenerationError(fmt_str % (name, interface_name)) from err

        try:
            signature = "".join(e.attrib["type"] for e in inargs)
        except KeyError as err:  # pragma: no cover
            fmt_str = (
                "No type attribute found for some argument for method "
                '"%s" belonging to interface "%s"'
            )
            raise DPClientGenerationError(fmt_str % (name, interface_name)) from err

        try:
            func = xformer(signature)
        except IntoDPError as err:  # pragma: no cover
            fmt_str = (
                "Failed to generate argument-transforming function "
                'from signature "%s" for method "%s" belonging to '
                'interface "%s"'
            )
            raise DPClientGenerationError(
                fmt_str % (signature, name, interface_name)
            ) from err
        arg_names_set = frozenset(arg_names)

        def dbus_func(proxy_object, func_args):  # pragma: no cover
            """
            The method proper.

            :param func_args: The function arguments
            :type func_args: dict
            :raises DPClientRuntimeError:
            """
            if arg_names_set != frozenset(func_args.keys()):
                param_list = list(arg_names_set)
                arg_list = list(func_args.keys())
                err_msg = (
                    f"Argument keywords passed ({', '.join(arg_list)}) did not match "
                    f"argument keywords expected ({', '.join(param_list)}) "
                    f'for method "{name}" '
                    f'belonging to interface "{interface_name}"',
                )
                raise DPClientKeywordError(
                    err_msg, interface_name, name, arg_list, param_list
                )

            args = [
                v
                for (k, v) in sorted(
                    func_args.items(), key=lambda x: arg_names.index(x[0])
                )
            ]

            try:
                xformed_args = func(args)
            except IntoDPError as err:
                arg_str = ", ".join(str(arg) for arg in args)
                err_msg = (
                    f"Failed to format arguments ({arg_str}) according to "
                    f'signature "{signature}" for method "{name}" belonging to '
                    f'interface "{interface_name}"'
                )
                raise DPClientMarshallingError(
                    err_msg, interface_name, signature, args
                ) from err

            dbus_method = proxy_object.get_dbus_method(
                name, dbus_interface=interface_name
            )

            try:
                return dbus_method(*xformed_args, signature=signature, timeout=timeout)
            except dbus.DBusException as err:
                arg_str = ", ".join(str(arg) for arg in xformed_args)
                err_msg = (
                    f'Error while invoking method "{name}" belonging to '
                    f'interface "{interface_name}" with arguments ({arg_str})'
                )
                raise DPClientInvocationError(
                    err_msg,
                    interface_name,
                    DPClientMethodCallContext(name, xformed_args),
                ) from err

        return dbus_func
Example #12
0
 def test_bad_array_value(self):
     """
     Verify that passing a dict for an array will raise an exception.
     """
     with self.assertRaises(IntoDPError):
         xformer('a(qq)')([dict()])