Exemple #1
0
    def test_hotspot_overhead(self):
        # Set SCALE to 5000 or something big to see how hotspot overhead
        # diminishes the more work the target function does.
        # It's low in this test suite because people like fast tests.
        SCALE = 100
        val = [dict((str(i), i) for i in xrange(100))] * SCALE
        start = time.time()
        to_columns(val)
        unpatched = time.time() - start

        probe = probes.attach_to("diagnose.test_fixtures.to_columns")
        try:
            probe.start()
            probe.instruments["instrument1"] = ProbeTestInstrument(
                expires=datetime.datetime.utcnow() +
                datetime.timedelta(minutes=10),
                name="to_columns.slowest.time",
                value="hotspots.worst.time",
                custom={
                    "tags":
                    '{"source": "%s:%s" % (hotspots.worst.lineno, hotspots.worst.source)}'
                },
            )
            start = time.time()
            to_columns(val)
            patched = time.time() - start
        finally:
            probe.stop()

        print("\nUNPATCHED: %s PATCHED: %s (%s%%)" %
              (unpatched, patched, int((patched / unpatched) * 100)))
Exemple #2
0
 def test_probe_bad_mock(self):
     p = probes.attach_to("diagnose.test_fixtures.Thing.notamethod")
     with self.assertRaises(AttributeError) as exc:
         p.start()
     assert (
         exc.exception.args[0] ==
         "diagnose.test_fixtures.Thing does not have the attribute 'notamethod'"
     )
Exemple #3
0
 def test_patch_class_decorated(self):
     probe = probes.attach_to("diagnose.test_fixtures.sum4")
     try:
         probe.start()
         instr = ProbeTestInstrument("deco", "arg4", event="call")
         probe.instruments["deco"] = instr
         assert sum4(1, 2, 3, 4) == 10
         assert instr.results == [4]
     finally:
         probe.stop()
Exemple #4
0
 def test_patch_wrapped_function_end_event(self):
     probe = probes.attach_to("diagnose.test_fixtures.Thing.add5")
     try:
         probe.start()
         instr = ProbeTestInstrument("deco", "arg1", event="end")
         probe.instruments["deco"] = instr
         Thing().add5(13)
         assert instr.results == [113]
     finally:
         probe.stop()
Exemple #5
0
    def test_probe_bad_mock(self):
        p = probes.attach_to("diagnose.test_fixtures.Thing.notamethod")
        with self.assertRaises(AttributeError) as exc:
            p.start()

        if six.PY2:
            expected_message = "diagnose.test_fixtures.Thing does not have the attribute 'notamethod'"
        else:
            expected_message = "<class 'diagnose.test_fixtures.Thing'> does not have the attribute 'notamethod'"

        assert (exc.exception.args[0] == expected_message)
Exemple #6
0
 def test_end_event_success(self):
     probe = probes.attach_to("diagnose.test_fixtures.a_func")
     try:
         probe.start()
         probe.instruments["instrument1"] = i = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="a_func",
             value="output",
             event="end",
             custom=None,
         )
         assert a_func(27) == 40
         assert i.results == [40]
     finally:
         probe.stop()
Exemple #7
0
    def __call__(self, f):
        """Use self as a decorator, attaching a probe to the wrapped function."""
        classname = sys._getframe(1).f_code.co_name
        if classname == "<module>":
            target = "%s.%s" % (f.__module__, getattr(f, "__name__", None) or getattr(f, "func_name"))
        else:
            target = "%s.%s.%s" % (f.__module__, classname, getattr(f, "__name__", None) or getattr(f, "func_name"))

        probe = probes.attach_to(target)
        # If we prefix the spec_id with self.mgr.short_id, then that
        # manager would immediately remove this instrument because
        # it's not in self.mgr.specs!
        # Use a hardcoded prefix instead so no manager drops it.
        probe.instruments["hardcode:%s" % (hash(target),)] = self

        return f
Exemple #8
0
 def test_return_event_locals_frame(self):
     probe = probes.attach_to("diagnose.test_fixtures.a_func")
     try:
         probe.start()
         probe.instruments["instrument1"] = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="a_func",
             value="frame.f_back.f_code.co_name",
             custom=None,
         )
         a_func(923775)
         assert probe.instruments["instrument1"].results == [
             "test_return_event_locals_frame"
         ]
     finally:
         probe.stop()
Exemple #9
0
 def test_end_event_exception_in_target(self):
     probe = probes.attach_to("diagnose.test_fixtures.a_func")
     try:
         probe.start()
         probe.instruments["instrument1"] = i = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="a_func",
             value="extra",
             event="end",
             custom=None,
         )
         with self.assertRaises(TypeError):
             a_func(None)
         self.assertEqual(i.results, [13])
     finally:
         probe.stop()
Exemple #10
0
 def test_slowest_line(self):
     probe = probes.attach_to("diagnose.test_fixtures.hard_work")
     try:
         probe.start()
         probe.instruments["instrument1"] = i = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="hard_work.slowest.time",
             value="hotspots.worst.time",
             custom={
                 "tags":
                 '{"source": "%s:%s" % (hotspots.worst.lineno, hotspots.worst.source)}'
             },
         )
         assert hard_work(0, 10000) == 1000
         assert [tags for tags, value in i.log] == [[
             "source:34:    summary = len([x for x in output if x % 10 == 0])\n"
         ]]
         assert [type(value) for tags, value in i.log] == [float]
     finally:
         probe.stop()
Exemple #11
0
 def test_return_event_exception_in_target(self):
     probe = probes.attach_to("diagnose.test_fixtures.a_func")
     try:
         probe.start()
         probe.instruments["instrument1"] = i = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="a_func",
             value="result",
             event="return",
             custom=None,
         )
         with self.assertRaises(TypeError):
             a_func(None)
         self.assertEqual(len(i.results), 1)
         self.assertEqual(type(i.results[0]), TypeError)
         self.assertEqual(
             i.results[0].args,
             ("unsupported operand type(s) for +: 'NoneType' and 'int'", ),
         )
     finally:
         probe.stop()
Exemple #12
0
 def test_end_event_exception_in_value(self):
     probe = probes.attach_to("diagnose.test_fixtures.a_func")
     try:
         errs = []
         old_handle_error = diagnose.manager.handle_error
         diagnose.manager.handle_error = lambda probe, instr: errs.append(
             sys.exc_info()[1].args[0] if sys.exc_info()[1].args[0] else "")
         probe.start()
         probe.instruments["instrument1"] = i = ProbeTestInstrument(
             expires=datetime.datetime.utcnow() +
             datetime.timedelta(minutes=10),
             name="a_func",
             value="unknown",  # Should throw NameError
             event="end",
             custom=None,
         )
         assert a_func(1000) == 1013
         assert i.results == []
         assert i.expires == i.error_expiration
         assert errs == ["name 'unknown' is not defined"]
     finally:
         diagnose.manager.handle_error = old_handle_error
         probe.stop()
Exemple #13
0
 def test_probe_nonfunc(self):
     # We REALLY should not be allowed to patch anything
     # that's not a function!
     p = probes.attach_to("diagnose.test_fixtures.Thing")
     with self.assertRaises(TypeError):
         p.start()
Exemple #14
0
    def test_target_copies(self):
        # When module M chooses "from x import y", then mock.patching x.y
        # does not affect M.y. Similarly, an existing object instance I
        # which has I.y = y is not patched by mock.patch.
        # Assert that FunctionProbe patches (and UNpatches) all such copies of y.
        old_probes_func_2 = func_2
        old_local_func_2 = func_2

        class Entity(object):
            pass

        t = Entity()
        t.add13 = func_2
        self.assertTrue(t.add13 is old_local_func_2)

        t2 = Entity()
        t2.add13 = func_2
        self.assertTrue(t2.add13 is old_local_func_2)

        registry["in_a_dict"] = func_2
        self.assertTrue(registry["in_a_dict"] is old_local_func_2)

        probe = probes.attach_to("diagnose.test_fixtures.func_2")
        try:
            probe.start()
            probe.instruments["instrument1"] = i = ProbeTestInstrument(
                expires=datetime.datetime.utcnow() +
                datetime.timedelta(minutes=10),
                name="func_2",
                value="arg",
                custom=None,
            )

            # Invoking x.y is typical and works naturally...
            self.assertTrue(func_2 is not old_probes_func_2)
            func_2(44)
            self.assertEqual(i.results, [44])

            # ...but invoking M.y (we imported func_2 into test_probes' namespace)
            # is harder:
            self.assertTrue(func_2 is not old_local_func_2)
            func_2(99999)
            self.assertEqual(i.results, [44, 99999])

            # ...and invoking Entity().y is just as hard:
            self.assertTrue(t.add13 is not old_local_func_2)
            self.assertTrue(t2.add13 is not old_local_func_2)
            t.add13(1001)
            self.assertEqual(i.results, [44, 99999, 1001])

            # ...etc:
            self.assertTrue(registry["in_a_dict"] is not old_local_func_2)
            registry["in_a_dict"](777)
            self.assertEqual(i.results, [44, 99999, 1001, 777])

            # The next problem is that, while our patch is live,
            # if t2 goes out of its original scope, we've still got
            # a reference to it in our mock patch.
            self.assertEqual(
                owner_types(func_2),
                {
                    types.ModuleType: 2,
                    Entity: 2,
                    probes.WeakMethodPatch: 3,
                    MockPatch: 1,
                    probes.DictPatch: 1,
                },
            )
            del t2
            self.assertEqual(
                owner_types(func_2),
                {
                    types.ModuleType:
                    2,
                    # The number of Entity references MUST decrease by 1.
                    Entity:
                    1,
                    # The number of WeakMethodPatch references MUST decrease by 1.
                    probes.WeakMethodPatch:
                    2,
                    MockPatch:
                    1,
                    probes.DictPatch:
                    1,
                },
            )
        finally:
            probe.stop()

        # All patches MUST be stopped
        assert func_2 is old_probes_func_2
        assert func_2 is old_local_func_2
        assert t.add13 is old_local_func_2
        func_2(123)
        func_2(456)
        t.add13(789)
        registry["in_a_dict"](101112)
        assert i.results == [44, 99999, 1001, 777]