示例#1
0
def patch():
    """
    The CursorWrapper is a pretty small wrapper around the cursor.
    If you are NOT in debug mode, this is the wrapper that's used.
    Sadly if it's in debug mode, we get a different wrapper for version earlier than 1.6.
    """

    def execute(orig_execute, self, *args, **kwargs):
        with statsd.timer(key(self.db, 'execute')):
            return orig_execute(self, *args, **kwargs)

    def executemany(orig_executemany, self, *args, **kwargs):
        with statsd.timer(key(self.db, 'executemany')):
            return orig_executemany(self, *args, **kwargs)

    def callproc(orig_callproc, self, *args, **kwargs):
        with statsd.timer(key(self.db, 'callproc')):
            return orig_callproc(self, *args, **kwargs)

    if django.VERSION > (1, 6):
        # In 1.6+ util.CursorDebugWrapper just makes calls to CursorWrapper
        # As such, we only need to instrument CursorWrapper.
        # Instrumenting both will result in duplicated metrics
        patch_method(util.CursorWrapper, 'execute')(execute)
        patch_method(util.CursorWrapper, 'executemany')(executemany)
        patch_method(util.CursorWrapper, 'callproc')(callproc)
    else:
        util.CursorWrapper.__getattr__ = pre_django_1_6_cursorwrapper_getattr
        patch_method(util.CursorDebugWrapper, 'execute')(execute)
        patch_method(util.CursorDebugWrapper, 'executemany')(executemany)
示例#2
0
    def test_late_patching(self):
        """
        Objects created before patching should get patched as well.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return original_fn(self, *args, **kwargs) + 10

        obj = self.cls()
        self.assertEqual(obj.sumargs(1, 2, 3, 4), 10)
        utils.patch_method(self.cls, 'sumargs')(patch_fn)
        self.assertEqual(obj.sumargs(1, 2, 3, 4), 20)
示例#3
0
    def test_late_patching(self):
        """
        Objects created before patching should get patched as well.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return original_fn(self, *args, **kwargs) + 10

        obj = self.cls()
        self.assertEqual(obj.sumargs(1, 2, 3, 4), 10)
        utils.patch_method(self.cls, 'sumargs')(patch_fn)
        self.assertEqual(obj.sumargs(1, 2, 3, 4), 20)
示例#4
0
    def test_args_kwargs_are_honored(self):
        """
        Args and kwargs must be honored between calls from the patched to
        the original version.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return original_fn(self, *args, **kwargs)

        utils.patch_method(self.cls, 'sumargs')(patch_fn)
        obj = self.cls()
        self.assertEqual(obj.sumargs(1, 2), 10)
        self.assertEqual(obj.sumargs(1, 1, d=1), 6)
        self.assertEqual(obj.sumargs(1, 1, 1, 1), 4)
示例#5
0
    def test_args_kwargs_are_honored(self):
        """
        Args and kwargs must be honored between calls from the patched to
        the original version.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return original_fn(self, *args, **kwargs)

        utils.patch_method(self.cls, 'sumargs')(patch_fn)
        obj = self.cls()
        self.assertEqual(obj.sumargs(1, 2), 10)
        self.assertEqual(obj.sumargs(1, 1, d=1), 6)
        self.assertEqual(obj.sumargs(1, 1, 1, 1), 4)
示例#6
0
    def test_patched_fn_can_receive_arbitrary_arguments(self):
        """
        Args and kwargs can be received arbitrarily with no contraints on
        the patched fn, even if the original_fn had a fixed set of
        allowed args and kwargs.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return args, kwargs

        utils.patch_method(self.cls, 'badfn')(patch_fn)
        obj = self.cls()
        self.assertEqual(obj.badfn(1, d=2), ((1, ), {'d': 2}))
        self.assertEqual(obj.badfn(1, d=2), ((1, ), {'d': 2}))
        self.assertEqual(obj.badfn(1, 2, c=1, d=2), ((1, 2), {'c': 1, 'd': 2}))
示例#7
0
    def test_doesnt_call_original_implicitly(self):
        """
        Original fn must be called explicitly from patched to be
        executed.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return 10

        with self.assertRaises(ValueError):
            obj = self.cls()
            obj.badfn(1, 2)

        utils.patch_method(self.cls, 'badfn')(patch_fn)
        self.assertEqual(obj.badfn(1, 2), 10)
示例#8
0
    def test_patched_fn_can_receive_arbitrary_arguments(self):
        """
        Args and kwargs can be received arbitrarily with no contraints on
        the patched fn, even if the original_fn had a fixed set of
        allowed args and kwargs.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return args, kwargs

        utils.patch_method(self.cls, 'badfn')(patch_fn)
        obj = self.cls()
        self.assertEqual(obj.badfn(1, d=2), ((1,), {'d': 2}))
        self.assertEqual(obj.badfn(1, d=2), ((1,), {'d': 2}))
        self.assertEqual(obj.badfn(1, 2, c=1, d=2), ((1, 2), {'c': 1, 'd': 2}))
示例#9
0
    def test_doesnt_call_original_implicitly(self):
        """
        Original fn must be called explicitly from patched to be
        executed.
        """
        def patch_fn(original_fn, self, *args, **kwargs):
            return 10

        with self.assertRaises(ValueError):
            obj = self.cls()
            obj.badfn(1, 2)

        utils.patch_method(self.cls, 'badfn')(patch_fn)
        self.assertEqual(obj.badfn(1, 2), 10)
示例#10
0
def patch():
    """
    The CursorWrapper is a pretty small wrapper around the cursor.  If
    you are NOT in debug mode, this is the wrapper that's used.  Sadly
    if it's in debug mode, we get a different wrapper for version
    earlier than 1.6.
    """

    if django.VERSION > (1, 6):
        # In 1.6+ util.CursorDebugWrapper just makes calls to CursorWrapper
        # As such, we only need to instrument CursorWrapper.
        # Instrumenting both will result in duplicated metrics
        patch_method(util.CursorWrapper, "execute")(patched_execute)
        patch_method(util.CursorWrapper, "executemany")(patched_executemany)
        patch_method(util.CursorWrapper, "callproc")(patched_callproc)
    else:
        util.CursorWrapper.__getattr__ = pre_django_1_6_cursorwrapper_getattr
        patch_method(util.CursorDebugWrapper, "execute")(patched_execute)
        patch_method(util.CursorDebugWrapper, "executemany")(patched_executemany)
示例#11
0
def patch():
    """
    The CursorWrapper is a pretty small wrapper around the cursor.  If
    you are NOT in debug mode, this is the wrapper that's used.  Sadly
    if it's in debug mode, we get a different wrapper for version
    earlier than 1.6.
    """

    if django.VERSION > (1, 6):
        # In 1.6+ util.CursorDebugWrapper just makes calls to CursorWrapper
        # As such, we only need to instrument CursorWrapper.
        # Instrumenting both will result in duplicated metrics
        patch_method(util.CursorWrapper, 'execute')(patched_execute)
        patch_method(util.CursorWrapper, 'executemany')(patched_executemany)
        patch_method(util.CursorWrapper, 'callproc')(patched_callproc)
    else:
        util.CursorWrapper.__getattr__ = pre_django_1_6_cursorwrapper_getattr
        patch_method(util.CursorDebugWrapper, 'execute')(patched_execute)
        patch_method(
            util.CursorDebugWrapper, 'executemany')(patched_executemany)
示例#12
0
def patch():
    """
    The CursorWrapper is a pretty small wrapper around the cursor.  If
    you are NOT in debug mode, this is the wrapper that's used.
    """
    patch_method(util.CursorWrapper, 'execute')(patched_execute)
    patch_method(util.CursorWrapper, 'executemany')(patched_executemany)
    patch_method(util.CursorWrapper, 'callproc')(patched_callproc)