Пример #1
0
class TrackClassTestCase(unittest.TestCase):

    def setUp(self):
        self.tracker = ClassTracker()

    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()

    def test_type_errors(self):
        """Test invalid parameters for class tracking.
        """
        i = 42
        j = 'Foobar'
        k = [i,j]
        l = {i: j}
        foo = Foo()
        bar = Bar()

        self.assertRaises(TypeError, self.tracker.track_class, i)
        self.assertRaises(TypeError, self.tracker.track_class, j)
        self.assertRaises(TypeError, self.tracker.track_class, k)
        self.assertRaises(TypeError, self.tracker.track_class, l)
        self.assertRaises(TypeError, self.tracker.track_class, foo)
        self.assertRaises(TypeError, self.tracker.track_class, bar)

        self.assert_(id(i) not in self.tracker.objects)
        self.assert_(id(j) not in self.tracker.objects)
        self.assert_(id(k) not in self.tracker.objects)
        self.assert_(id(l) not in self.tracker.objects)

    def test_track_class(self):
        """Test tracking objects through classes.
        """
        self.tracker.track_class(Foo)
        self.tracker.track_class(Bar)
        self.tracker.track_class(Empty)
        self.tracker.track_class(Foo)

        foo = Foo()
        bar = Bar()
        empty = Empty()

        self.assert_(id(foo) in self.tracker.objects)
        self.assert_(id(bar) in self.tracker.objects)
        self.assert_(id(empty) in self.tracker.objects)

    def test_track_class_new(self):
        """Test tracking new style classes.
        """
        self.tracker.track_class(FooNew)
        self.tracker.track_class(BarNew)

        foo = FooNew()
        bar = BarNew()

        self.assert_(id(foo) in self.tracker.objects)
        self.assert_(id(bar) in self.tracker.objects)

    def test_track_by_name(self):
        """Test registering objects by name.
        """
        self.tracker.track_class(Foo, name='Foobar')

        foo = Foo()

        self.assert_('Foobar' in self.tracker.index        )
        self.assertEqual(self.tracker.index['Foobar'][0].ref(),foo)

    def test_keep(self):
        """Test lifetime of tracked objects.
        """
        self.tracker.track_class(Foo, keep=1)
        self.tracker.track_class(Bar)

        foo = Foo()
        bar = Bar()

        idfoo = id(foo)
        idbar = id(bar)

        del foo
        del bar

        self.assert_(self.tracker.objects[idfoo].ref() is not None)
        self.assert_(self.tracker.objects[idbar].ref() is None)

    def test_class_history(self):
        """Test instance history of tracked class.
        """
        self.tracker.track_class(Foo, name='Foo')
        f1 = Foo()
        f2 = Foo()
        f3 = Foo()
        del f1
        del f2
        f4 = Foo()
        del f3
        del f4

        instances = [cnt for _, cnt in self.tracker.history['Foo']]
        self.assertEqual(instances, [1, 2, 3, 2, 1, 2, 1, 0])

    def test_trace(self):
        """Test instantiation tracing of tracked objects.
        """
        from inspect import stack

        self.tracker.track_class(Foo, trace=True)
        self.tracker.track_class(BarNew, trace=True)

        foo = Foo()
        bar = BarNew()

        idfoo = id(foo)
        idbar = id(bar)

        trace = []
        st = stack()
        try:
            for fr in st:
                trace.insert(0, fr[1:])
        finally:
            del st

        self.assertEqual(self.tracker.objects[idfoo].trace[-1][3][0].strip(),"foo = Foo()")
        self.assertEqual(self.tracker.objects[idfoo].trace[:-1],trace[:-1], trace)
        self.assertEqual(self.tracker.objects[idbar].trace[:-1],trace[:-1], trace)

    def test_detach(self):
        """Test detaching from tracked classes.
        """
        self.tracker.track_class(Foo)
        self.tracker.track_class(Bar)

        foo = Foo()
        bar = Bar()

        self.assert_(id(foo) in self.tracker.objects)
        self.assert_(id(bar) in self.tracker.objects)

        self.tracker.detach_class(Foo)
        self.tracker.detach_class(Bar)

        foo2 = Foo()
        bar2 = Bar()

        self.assert_(id(foo2) not in self.tracker.objects)
        self.assert_(id(bar2) not in self.tracker.objects)

        self.assertRaises(KeyError, self.tracker.detach_class, Foo)

    def test_change_name(self):
        """Test modifying name.
        """
        self.tracker.track_class(Foo, name='Foobar')
        self.tracker.track_class(Foo, name='Baz')
        foo = Foo()

        self.assert_('Foobar' not in self.tracker.index)
        self.assert_('Baz' in self.tracker.index)
        self.assertEqual(self.tracker.index['Baz'][0].ref(),foo)
Пример #2
0
class SnapshotTestCase(unittest.TestCase):

    def setUp(self):
        self.tracker = ClassTracker()

    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()

    def test_timestamp(self):
        """Test timestamp of snapshots.
        """
        foo = Foo()
        bar = Bar()

        self.tracker.track_object(foo)
        self.tracker.track_object(bar)

        self.tracker.create_snapshot()
        self.tracker.create_snapshot()
        self.tracker.create_snapshot()

        refts = [fp.timestamp for fp in self.tracker.snapshots]
        for to in self.tracker.objects.values():
            ts = [t for (t,sz) in to.snapshots[1:]]
            self.assertEqual(ts,refts)

    def test_snapshot_members(self):
        """Test existence and value of snapshot members.
        """
        foo = Foo()
        self.tracker.track_object(foo)
        self.tracker.create_snapshot()
        self.tracker.create_snapshot(compute_total=True)

        fp = self.tracker.snapshots[0]
        fp_with_total = self.tracker.snapshots[1]

        self.assert_(fp.overhead > 0, fp.overhead)
        self.assert_(fp.tracked_total > 0, fp.tracked_total)
        self.assertEqual(fp.asizeof_total, 0)

        self.assert_(fp_with_total.asizeof_total > 0, fp_with_total.asizeof_total)
        self.assert_(fp_with_total.asizeof_total >= fp_with_total.tracked_total)

        if pympler.process.is_available():
            procmem = fp.system_total
            self.assertEqual(fp.total, procmem.vsz)
            self.assert_(procmem.vsz > 0, procmem)
            self.assert_(procmem.rss > 0, procmem)
            self.assertTrue(procmem.vsz >= procmem.rss, procmem)
            self.assert_(procmem.vsz > fp.overhead, procmem)
            self.assert_(procmem.vsz > fp.tracked_total, procmem)
            self.assert_(fp_with_total.system_total.vsz > fp_with_total.asizeof_total)
        else:
            self.assertEqual(fp_with_total.total, fp_with_total.asizeof_total)
            self.assertEqual(fp.total, fp.tracked_total)


    def test_desc(self):
        """Test snapshot label.
        """
        self.tracker.create_snapshot()
        self.tracker.create_snapshot('alpha')
        self.tracker.create_snapshot(description='beta')
        self.tracker.create_snapshot(42)

        self.assertEqual(len(self.tracker.snapshots), 4)
        self.assertEqual(self.tracker.snapshots[0].desc, '')
        self.assertEqual(self.tracker.snapshots[1].desc, 'alpha')
        self.assertEqual(self.tracker.snapshots[2].desc, 'beta')
        self.assertEqual(self.tracker.snapshots[3].desc, '42')

        snapshot = self.tracker.snapshots[0]
        self.assertEqual(snapshot.label, '%.3fs' % snapshot.timestamp)
        snapshot = self.tracker.snapshots[1]
        self.assertEqual(snapshot.label, 'alpha (%.3fs)' % snapshot.timestamp)
        snapshot = self.tracker.snapshots[3]
        self.assertEqual(snapshot.label, '42 (%.3fs)' % snapshot.timestamp)


    def test_background_monitoring(self):
        """Test background monitoring.
        """
        self.tracker.start_periodic_snapshots(0.1)
        self.assertEqual(self.tracker._periodic_thread.interval, 0.1)
        self.assertEqual(self.tracker._periodic_thread.getName(), 'BackgroundMonitor')
        for x in range(10): # try to interfere
            self.tracker.create_snapshot(str(x))
        time.sleep(0.5)
        self.tracker.start_periodic_snapshots(0.2)
        self.assertEqual(self.tracker._periodic_thread.interval, 0.2)
        self.tracker.stop_periodic_snapshots()
        self.assert_(self.tracker._periodic_thread is None)
        self.assert_(len(self.tracker.snapshots) > 10)
Пример #3
0
class TrackClassTestCase(unittest.TestCase):
    def setUp(self):
        self.tracker = ClassTracker()

    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()

    def test_type_errors(self):
        """Test invalid parameters for class tracking.
        """
        i = 42
        j = 'Foobar'
        k = [i, j]
        l = {i: j}
        foo = Foo()
        bar = Bar()

        self.assertRaises(TypeError, self.tracker.track_class, i)
        self.assertRaises(TypeError, self.tracker.track_class, j)
        self.assertRaises(TypeError, self.tracker.track_class, k)
        self.assertRaises(TypeError, self.tracker.track_class, l)
        self.assertRaises(TypeError, self.tracker.track_class, foo)
        self.assertRaises(TypeError, self.tracker.track_class, bar)

        self.assertTrue(id(i) not in self.tracker.objects)
        self.assertTrue(id(j) not in self.tracker.objects)
        self.assertTrue(id(k) not in self.tracker.objects)
        self.assertTrue(id(l) not in self.tracker.objects)

    def test_track_class(self):
        """Test tracking objects through classes.
        """
        self.tracker.track_class(Foo)
        self.tracker.track_class(Bar)
        self.tracker.track_class(Empty)
        self.tracker.track_class(Foo)

        foo = Foo()
        bar = Bar()
        empty = Empty()

        self.assertTrue(id(foo) in self.tracker.objects)
        self.assertTrue(id(bar) in self.tracker.objects)
        self.assertTrue(id(empty) in self.tracker.objects)

    def test_track_class_new(self):
        """Test tracking new style classes.
        """
        self.tracker.track_class(FooNew)
        self.tracker.track_class(BarNew)

        foo = FooNew()
        bar = BarNew()

        self.assertTrue(id(foo) in self.tracker.objects)
        self.assertTrue(id(bar) in self.tracker.objects)

    def test_track_by_name(self):
        """Test registering objects by name.
        """
        self.tracker.track_class(Foo, name='Foobar')

        foo = Foo()

        self.assertTrue('Foobar' in self.tracker.index)
        self.assertEqual(self.tracker.index['Foobar'][0].ref(), foo)

    def test_keep(self):
        """Test lifetime of tracked objects.
        """
        self.tracker.track_class(Foo, keep=1)
        self.tracker.track_class(Bar)

        foo = Foo()
        bar = Bar()

        idfoo = id(foo)
        idbar = id(bar)

        del foo
        del bar

        self.assertTrue(self.tracker.objects[idfoo].ref() is not None)
        self.assertTrue(self.tracker.objects[idbar].ref() is None)

    def test_class_history(self):
        """Test instance history of tracked class.
        """
        self.tracker.track_class(Foo, name='Foo')
        f1 = Foo()
        f2 = Foo()
        f3 = Foo()
        del f1
        del f2
        f4 = Foo()
        del f3
        del f4

        instances = [cnt for _, cnt in self.tracker.history['Foo']]
        self.assertEqual(instances, [1, 2, 3, 2, 1, 2, 1, 0])

    def test_trace(self):
        """Test instantiation tracing of tracked objects.
        """
        from inspect import stack

        self.tracker.track_class(Foo, trace=True)
        self.tracker.track_class(BarNew, trace=True)

        foo = Foo()
        bar = BarNew()

        idfoo = id(foo)
        idbar = id(bar)

        trace = []
        st = stack()
        try:
            for fr in st:
                trace.insert(0, fr[1:])
        finally:
            del st

        self.assertEqual(self.tracker.objects[idfoo].trace[-1][3][0].strip(),
                         "foo = Foo()")
        self.assertEqual(self.tracker.objects[idfoo].trace[:-1], trace[:-1],
                         trace)
        self.assertEqual(self.tracker.objects[idbar].trace[:-1], trace[:-1],
                         trace)

    def test_detach(self):
        """Test detaching from tracked classes.
        """
        self.tracker.track_class(Foo)
        self.tracker.track_class(Bar)

        foo = Foo()
        bar = Bar()

        self.assertTrue(id(foo) in self.tracker.objects)
        self.assertTrue(id(bar) in self.tracker.objects)

        self.tracker.detach_class(Foo)
        self.tracker.detach_class(Bar)

        foo2 = Foo()
        bar2 = Bar()

        self.assertTrue(id(foo2) not in self.tracker.objects)
        self.assertTrue(id(bar2) not in self.tracker.objects)

        self.assertRaises(KeyError, self.tracker.detach_class, Foo)

    def test_change_name(self):
        """Test modifying name.
        """
        self.tracker.track_class(Foo, name='Foobar')
        self.tracker.track_class(Foo, name='Baz')
        foo = Foo()

        self.assertTrue('Foobar' not in self.tracker.index)
        self.assertTrue('Baz' in self.tracker.index)
        self.assertEqual(self.tracker.index['Baz'][0].ref(), foo)
Пример #4
0
class SnapshotTestCase(unittest.TestCase):
    def setUp(self):
        self.tracker = ClassTracker()

    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()

    def test_timestamp(self):
        """Test timestamp of snapshots.
        """
        foo = Foo()
        bar = Bar()

        self.tracker.track_object(foo)
        self.tracker.track_object(bar)

        self.tracker.create_snapshot()
        self.tracker.create_snapshot()
        self.tracker.create_snapshot()

        refts = [fp.timestamp for fp in self.tracker.snapshots]
        for to in self.tracker.objects.values():
            ts = [t for (t, sz) in to.snapshots[1:]]
            self.assertEqual(ts, refts)

    def test_snapshot_members(self):
        """Test existence and value of snapshot members.
        """
        foo = Foo()
        self.tracker.track_object(foo)
        self.tracker.create_snapshot()
        self.tracker.create_snapshot(compute_total=True)

        fp = self.tracker.snapshots[0]
        fp_with_total = self.tracker.snapshots[1]

        self.assertTrue(fp.overhead > 0, fp.overhead)
        self.assertTrue(fp.tracked_total > 0, fp.tracked_total)
        self.assertEqual(fp.asizeof_total, 0)

        self.assertTrue(fp_with_total.asizeof_total > 0,
                        fp_with_total.asizeof_total)
        self.assertTrue(
            fp_with_total.asizeof_total >= fp_with_total.tracked_total)

        if pympler.process.is_available():
            procmem = fp.system_total
            self.assertEqual(fp.total, procmem.vsz)
            self.assertTrue(procmem.vsz > 0, procmem)
            self.assertTrue(procmem.rss > 0, procmem)
            self.assertTrue(procmem.vsz >= procmem.rss, procmem)
            self.assertTrue(procmem.vsz > fp.overhead, procmem)
            self.assertTrue(procmem.vsz > fp.tracked_total, procmem)
            self.assertTrue(
                fp_with_total.system_total.vsz > fp_with_total.asizeof_total)
        else:
            self.assertEqual(fp_with_total.total, fp_with_total.asizeof_total)
            self.assertEqual(fp.total, fp.tracked_total)

    def test_desc(self):
        """Test snapshot label.
        """
        self.tracker.create_snapshot()
        self.tracker.create_snapshot('alpha')
        self.tracker.create_snapshot(description='beta')
        self.tracker.create_snapshot(42)

        self.assertEqual(len(self.tracker.snapshots), 4)
        self.assertEqual(self.tracker.snapshots[0].desc, '')
        self.assertEqual(self.tracker.snapshots[1].desc, 'alpha')
        self.assertEqual(self.tracker.snapshots[2].desc, 'beta')
        self.assertEqual(self.tracker.snapshots[3].desc, '42')

        snapshot = self.tracker.snapshots[0]
        self.assertEqual(snapshot.label, '%.3fs' % snapshot.timestamp)
        snapshot = self.tracker.snapshots[1]
        self.assertEqual(snapshot.label, 'alpha (%.3fs)' % snapshot.timestamp)
        snapshot = self.tracker.snapshots[3]
        self.assertEqual(snapshot.label, '42 (%.3fs)' % snapshot.timestamp)

    def test_background_monitoring(self):
        """Test background monitoring.
        """
        self.tracker.start_periodic_snapshots(0.1)
        self.assertEqual(self.tracker._periodic_thread.interval, 0.1)
        self.assertEqual(self.tracker._periodic_thread.getName(),
                         'BackgroundMonitor')
        for x in range(10):  # try to interfere
            self.tracker.create_snapshot(str(x))
        time.sleep(0.5)
        self.tracker.start_periodic_snapshots(0.2)
        self.assertEqual(self.tracker._periodic_thread.interval, 0.2)
        self.tracker.stop_periodic_snapshots()
        self.assertTrue(self.tracker._periodic_thread is None)
        self.assertTrue(len(self.tracker.snapshots) > 10)
Пример #5
0
class LogTestCase(unittest.TestCase):

    def setUp(self):
        self.out = StringIO()
        self.tracker = ClassTracker(stream=self.out)


    @property
    def output(self):
        """Return output recorded in `ClassTracker` output stream."""
        return self.out.getvalue()


    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()


    def test_dump(self):
        """Test serialization of log data.
        """
        foo = Foo()
        foo.data = range(1000)
        bar = Bar()

        self.tracker.track_object(foo, resolution_level=4)
        self.tracker.track_object(bar)

        self.tracker.create_snapshot('Footest')

        f1 = StringIO()
        f2 = StringIO()

        ConsoleStats(tracker=self.tracker, stream=f1).print_stats()

        tmp = BytesIO()
        Stats(tracker=self.tracker).dump_stats(tmp, close=False)

        self.tracker.clear()

        stats = ConsoleStats(stream=f2)
        self.assertEqual(stats.index, None)
        self.assertEqual(stats.snapshots, None)
        tmp.seek(0)
        stats.load_stats(tmp)
        tmp.close()
        self.assert_('Foo' in stats.index)

        stats.print_stats()

        self.assertEqual(f1.getvalue(), f2.getvalue())

        # Test partial printing
        stats.stream = f3 = StringIO()
        stats.sort_stats()
        tolen = len(stats.sorted)
        stats.print_stats(clsname='Bar')
        self.assertEqual(len(stats.sorted), tolen)
        stats.print_summary()
        clsname = f3.getvalue().split('\n')[0]
        self.assertNotEqual(re.search('Bar', clsname), None, clsname)

        f1.close()
        f2.close()
        f3.close()


    def test_sort_stats(self):
        """Test sort_stats and reverse_order.
        """
        self.tracker.track_class(Bar, name='Bar')
        foo = Foo()
        foo.data = list(range(1000))
        bar1 = Bar()
        bar2 = Bar()
        self.tracker.track_object(foo, resolution_level=4)
        self.tracker.create_snapshot()

        stats = self.tracker.stats

        # Test sort_stats and reverse_order
        self.assertEqual(stats.sort_stats('size'), stats)
        self.assertEqual(stats.sorted[0].classname, 'Foo')
        stats.reverse_order()
        self.assertEqual(stats.sorted[0].classname, 'Bar')
        stats.sort_stats('classname', 'birth')
        self.assertEqual(stats.sorted[0].classname, 'Bar')
        self.assertRaises(ValueError, stats.sort_stats, 'name', 42, 'classn')
        stats.sort_stats('classname')


    def test_dump_load_with_filename(self):
        """Test serialization with filename.
        """
        foo = Foo()
        self.tracker.track_object(foo, resolution_level=2)
        self.tracker.create_snapshot()
        fhandle, fname = mkstemp(prefix='pympler_test_dump')
        os.close(fhandle)
        try:
            self.tracker.stats.dump_stats(fname)
            output = StringIO()
            stats = ConsoleStats(filename=fname, stream=output)
            stats.print_stats()
            self.assertTrue('<Foo>' in output.getvalue(), output.getvalue())
            # Check if a Stats loaded from a dump can be dumped again
            stats.dump_stats(fname)
        finally:
            os.unlink(fname)


    def test_tracked_classes(self):
        """Test listing tracked classes.
        """
        self.tracker.track_class(Foo, name='Foo')
        self.tracker.track_class(Bar, name='Bar')

        foo = Foo()
        self.tracker.create_snapshot()
        bar = Bar()
        self.tracker.create_snapshot()
        foo = FooNew()
        self.tracker.track_object(foo)
        self.tracker.create_snapshot()

        stats = self.tracker.stats
        self.assertEqual(stats.tracked_classes, ['Bar', 'Foo', 'FooNew'])
        stats.print_summary()


    def test_print_stats(self):
        """Test printing class-filtered statistics.
        """
        self.tracker.track_class(Foo, name='Foo', trace=True)
        self.tracker.track_class(Bar, name='Bar')

        foo = Foo()
        bar = Bar()

        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats(clsname='Foo')
        self.assertTrue('Foo' in self.output, self.output)
        self.assertFalse('Bar' in self.output, self.output)
        self.assertTrue('foo = Foo()' in self.output, self.output)


    def test_print_stats_limit(self):
        """Test printing limited statistics.
        """
        self.tracker.track_class(Foo, name='Foo')

        foo = [Foo() for _ in range(10)]

        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats(limit=3)
        self.assertEqual(self.output.count('<Foo>'), 3)

        self.out.seek(0)
        self.out.truncate()

        stats.print_stats(limit=0.5)
        self.assertEqual(self.output.count('<Foo>'), 5)


    def test_snapshots(self):
        """Test multiple snapshots.
        """
        self.tracker.track_class(Foo, name='Foo')
        self.tracker.track_class(Bar, name='Bar')
        self.tracker.track_class(FooNew, name='FooNew')

        self.tracker.create_snapshot()
        f1 = Foo()
        self.tracker.create_snapshot()
        f2 = Foo()
        f3 = FooNew()
        self.tracker.create_snapshot()
        b = Bar()
        del b
        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats()
        stats.print_summary()


    def test_merge(self):
        """Test merging of reference trees.
        """
        self.tracker.track_class(FooNew, name='Foo', resolution_level=2)

        f1 = FooNew()
        f1.a = list(range(1000))
        f2 = FooNew()
        f2.a = list(range(100))
        f2.b = 'This is some stupid spam.'

        self.tracker.create_snapshot('Merge test')

        sizer = Asizer()
        sz1 = sizer.asized(f1)
        sz2 = sizer.asized(f2)

        stats = self.tracker.stats
        for fp in stats.snapshots:
            if fp.desc == 'Merge test':
                stats.annotate_snapshot(fp)
                self.assert_(hasattr(fp, 'classes'))
                classes = fp.classes
                stats.annotate_snapshot(fp)
                self.assertEqual(fp.classes, classes)
                self.assert_('Foo' in fp.classes, fp.classes)
                self.assert_('merged' in fp.classes['Foo'])
                fm = fp.classes['Foo']['merged']
                self.assertEqual(fm.size, sz1.size + sz2.size, (fm.size, str(sz1), str(sz2)))
                refs = {}
                for ref in fm.refs:
                    refs[ref.name] = ref
                self.assert_('__dict__' in refs.keys(), refs.keys())
                refs2 = {}
                for ref in refs['__dict__'].refs:
                    refs2[ref.name] = ref
                self.assert_('[V] a' in refs2.keys(), refs2.keys())
                self.assert_('[V] b' in refs2.keys(), refs2.keys())
                self.assertEqual(refs2['[V] a'].size, asizeof(f1.a, f2.a))


    def test_html(self):
        """Test emitting HTML statistics."""
        self.tracker.track_class(Foo, name='Foo', resolution_level=2)
        self.tracker.track_class(Bar, name='Bar', trace=True)

        f1 = Foo()
        f1.a = list(range(100000))
        f2 = Foo()
        f2.a = list(range(1000))
        f2.b = 'This is some stupid spam.'
        f1 = Bar()

        self.tracker.create_snapshot('Merge test')

        stats = HtmlStats(tracker=self.tracker)
        try:
            target = mkdtemp(prefix='pympler_test')
            output = os.path.join(target, 'footest.html')
            stats.create_html(output)

            source = open(output).read()
            # Ensure relative links are used
            fname = os.path.join('footest_files', 'Foo.html')
            self.assertTrue('<a href="%s">' % fname in source, (fname, source))
        finally:
            rmtree(target)


    def test_charts(self):
        """Test emitting graphic charts."""
        self.tracker.track_class(Foo, name='Foo', resolution_level=2)

        f1 = Foo()
        f1.a = list(range(1000))
        f2 = Foo()
        f2.a = list(range(100))
        f2.b = 'This is some stupid spam.'

        self.tracker.create_snapshot('Merge test')

        from pympler import charts
        try:
            target = mkdtemp(prefix='pympler_test')
            output = os.path.join(target, 'timespace.png')
            charts.tracker_timespace(output, self.tracker.stats)
        finally:
            rmtree(target)
Пример #6
0
class LogTestCase(unittest.TestCase):
    def setUp(self):
        self.out = StringIO()
        self.tracker = ClassTracker(stream=self.out)

    @property
    def output(self):
        """Return output recorded in `ClassTracker` output stream."""
        return self.out.getvalue()

    def tearDown(self):
        self.tracker.stop_periodic_snapshots()
        self.tracker.clear()

    def test_dump(self):
        """Test serialization of log data.
        """
        foo = Foo()
        foo.data = range(1000)
        bar = Bar()

        self.tracker.track_object(foo, resolution_level=4)
        self.tracker.track_object(bar)

        self.tracker.create_snapshot('Footest')

        f1 = StringIO()
        f2 = StringIO()

        ConsoleStats(tracker=self.tracker, stream=f1).print_stats()

        tmp = BytesIO()
        Stats(tracker=self.tracker).dump_stats(tmp, close=False)

        self.tracker.clear()

        stats = ConsoleStats(stream=f2)
        self.assertEqual(stats.index, None)
        self.assertEqual(stats.snapshots, None)
        tmp.seek(0)
        stats.load_stats(tmp)
        tmp.close()
        self.assert_('Foo' in stats.index)

        stats.print_stats()

        self.assertEqual(f1.getvalue(), f2.getvalue())

        # Test partial printing
        stats.stream = f3 = StringIO()
        stats.sort_stats()
        tolen = len(stats.sorted)
        stats.print_stats(clsname='Bar')
        self.assertEqual(len(stats.sorted), tolen)
        stats.print_summary()
        clsname = f3.getvalue().split('\n')[0]
        self.assertNotEqual(re.search('\.Bar', clsname), None, clsname)

        f1.close()
        f2.close()
        f3.close()

    def test_sort_stats(self):
        """Test sort_stats and reverse_order.
        """
        self.tracker.track_class(Bar, name='Bar')
        foo = Foo()
        foo.data = list(range(1000))
        bar1 = Bar()
        bar2 = Bar()
        self.tracker.track_object(foo, resolution_level=4)
        self.tracker.create_snapshot()

        stats = self.tracker.stats

        # Test sort_stats and reverse_order
        self.assertEqual(stats.sort_stats('size'), stats)
        self.assertEqual(stats.sorted[0].classname, 'Foo')
        stats.reverse_order()
        self.assertEqual(stats.sorted[0].classname, 'Bar')
        stats.sort_stats('classname', 'birth')
        self.assertEqual(stats.sorted[0].classname, 'Bar')
        self.assertRaises(ValueError, stats.sort_stats, 'name', 42, 'classn')
        stats.sort_stats('classname')

    def test_dump_load_with_filename(self):
        """Test serialization with filename.
        """
        foo = Foo()
        self.tracker.track_object(foo, resolution_level=2)
        self.tracker.create_snapshot()
        fhandle, fname = mkstemp(prefix='pympler_test_dump')
        os.close(fhandle)
        try:
            self.tracker.stats.dump_stats(fname)
            output = StringIO()
            stats = ConsoleStats(filename=fname, stream=output)
            stats.print_stats()
            self.assertTrue('<Foo>' in output.getvalue(), output.getvalue())
            # Check if a Stats loaded from a dump can be dumped again
            stats.dump_stats(fname)
        finally:
            os.unlink(fname)

    def test_tracked_classes(self):
        """Test listing tracked classes.
        """
        self.tracker.track_class(Foo, name='Foo')
        self.tracker.track_class(Bar, name='Bar')

        foo = Foo()
        self.tracker.create_snapshot()
        bar = Bar()
        self.tracker.create_snapshot()
        foo = FooNew()
        self.tracker.track_object(foo)
        self.tracker.create_snapshot()

        stats = self.tracker.stats
        self.assertEqual(stats.tracked_classes, ['Bar', 'Foo', 'FooNew'])
        stats.print_summary()

    def test_print_stats(self):
        """Test printing class-filtered statistics.
        """
        self.tracker.track_class(Foo, name='Foo', trace=True)
        self.tracker.track_class(Bar, name='Bar')

        foo = Foo()
        bar = Bar()

        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats(clsname='Foo')
        self.assertTrue('Foo' in self.output, self.output)
        self.assertFalse('Bar' in self.output, self.output)
        self.assertTrue('foo = Foo()' in self.output, self.output)

    def test_print_stats_limit(self):
        """Test printing limited statistics.
        """
        self.tracker.track_class(Foo, name='Foo')

        foo = [Foo() for _ in range(10)]

        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats(limit=3)
        self.assertEqual(self.output.count('<Foo>'), 3)

        self.out.seek(0)
        self.out.truncate()

        stats.print_stats(limit=0.5)
        self.assertEqual(self.output.count('<Foo>'), 5)

    def test_snapshots(self):
        """Test multiple snapshots.
        """
        self.tracker.track_class(Foo, name='Foo')
        self.tracker.track_class(Bar, name='Bar')
        self.tracker.track_class(FooNew, name='FooNew')

        self.tracker.create_snapshot()
        f1 = Foo()
        self.tracker.create_snapshot()
        f2 = Foo()
        f3 = FooNew()
        self.tracker.create_snapshot()
        b = Bar()
        del b
        self.tracker.create_snapshot()

        stats = self.tracker.stats
        stats.print_stats()
        stats.print_summary()

    def test_merge(self):
        """Test merging of reference trees.
        """
        self.tracker.track_class(FooNew, name='Foo', resolution_level=2)

        f1 = FooNew()
        f1.a = list(range(1000))
        f2 = FooNew()
        f2.a = list(range(100))
        f2.b = 'This is some stupid spam.'

        self.tracker.create_snapshot('Merge test')

        sizer = Asizer()
        sz1 = sizer.asized(f1)
        sz2 = sizer.asized(f2)

        stats = self.tracker.stats
        for fp in stats.snapshots:
            if fp.desc == 'Merge test':
                stats.annotate_snapshot(fp)
                self.assert_(hasattr(fp, 'classes'))
                classes = fp.classes
                stats.annotate_snapshot(fp)
                self.assertEqual(fp.classes, classes)
                self.assert_('Foo' in fp.classes, fp.classes)
                self.assert_('merged' in fp.classes['Foo'])
                fm = fp.classes['Foo']['merged']
                self.assertEqual(fm.size, sz1.size + sz2.size,
                                 (fm.size, str(sz1), str(sz2)))
                refs = {}
                for ref in fm.refs:
                    refs[ref.name] = ref
                self.assert_('__dict__' in refs.keys(), refs.keys())
                refs2 = {}
                for ref in refs['__dict__'].refs:
                    refs2[ref.name] = ref
                self.assert_('[V] a' in refs2.keys(), refs2.keys())
                self.assert_('[V] b' in refs2.keys(), refs2.keys())
                self.assertEqual(refs2['[V] a'].size, asizeof(f1.a, f2.a))

    def test_html(self):
        """Test emitting HTML statistics."""
        self.tracker.track_class(Foo, name='Foo', resolution_level=2)
        self.tracker.track_class(Bar, name='Bar', trace=True)

        f1 = Foo()
        f1.a = list(range(100000))
        f2 = Foo()
        f2.a = list(range(1000))
        f2.b = 'This is some stupid spam.'
        f1 = Bar()

        self.tracker.create_snapshot('Merge test')

        stats = HtmlStats(tracker=self.tracker)
        try:
            target = mkdtemp(prefix='pympler_test')
            output = os.path.join(target, 'footest.html')
            stats.create_html(output)

            source = open(output).read()
            # Ensure relative links are used
            fname = os.path.join('footest_files', 'Foo.html')
            self.assertTrue('<a href="%s">' % fname in source, (fname, source))
        finally:
            rmtree(target)

    def test_charts(self):
        """Test emitting graphic charts."""
        self.tracker.track_class(Foo, name='Foo', resolution_level=2)

        f1 = Foo()
        f1.a = list(range(1000))
        f2 = Foo()
        f2.a = list(range(100))
        f2.b = 'This is some stupid spam.'

        self.tracker.create_snapshot('Merge test')

        from pympler import charts
        try:
            target = mkdtemp(prefix='pympler_test')
            output = os.path.join(target, 'timespace.png')
            charts.tracker_timespace(output, self.tracker.stats)
        finally:
            rmtree(target)