/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_lsprof.py

  • Committer: Jelmer Vernooij
  • Date: 2018-07-08 14:45:27 UTC
  • mto: This revision was merged to the branch mainline in revision 7036.
  • Revision ID: jelmer@jelmer.uk-20180708144527-codhlvdcdg9y0nji
Fix a bunch of merge tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2007, 2009, 2010, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for profiling data collection."""
18
18
 
19
19
 
20
 
import cPickle
21
 
import os
22
 
 
23
 
import bzrlib
24
 
from bzrlib import tests
25
 
 
26
 
 
27
 
class _LSProfFeature(tests.Feature):
28
 
 
29
 
    def available(self):
30
 
        try:
31
 
            from bzrlib import lsprof
32
 
        except ImportError:
33
 
            return False
34
 
        else:
35
 
            return True
36
 
 
37
 
 
38
 
LSProfFeature = _LSProfFeature()
 
20
try:
 
21
    import cPickle as pickle
 
22
except ImportError:
 
23
    import pickle
 
24
import threading
 
25
 
 
26
from .. import (
 
27
    errors,
 
28
    osutils,
 
29
    tests,
 
30
    )
 
31
from ..tests import features
 
32
 
 
33
 
 
34
lsprof = features.lsprof_feature.module
39
35
 
40
36
 
41
37
_TXT_HEADER = "   CallCount    Recursive    Total(ms)   " + \
49
45
 
50
46
def _collect_stats():
51
47
    "Collect and return some dummy profile data."
52
 
    from bzrlib.lsprof import profile
53
 
    ret, stats = profile(_junk_callable)
 
48
    ret, stats = lsprof.profile(_junk_callable)
54
49
    return stats
55
50
 
56
51
 
57
 
class TestStatsSave(tests.TestCaseInTempDir):
 
52
class TestStats(tests.TestCaseInTempDir):
58
53
 
59
 
    _test_needs_features = [LSProfFeature]
 
54
    _test_needs_features = [features.lsprof_feature]
60
55
 
61
56
    def setUp(self):
62
57
        super(tests.TestCaseInTempDir, self).setUp()
63
58
        self.stats = _collect_stats()
64
59
 
65
 
    def _tempfile(self, ext):
66
 
        dir = self.test_dir
67
 
        return bzrlib.osutils.pathjoin(dir, "tmp_profile_data." + ext)
68
 
 
69
 
    def test_stats_save_to_txt(self):
70
 
        f = self._tempfile("txt")
71
 
        self.stats.save(f)
72
 
        lines = open(f).readlines()
73
 
        self.assertEqual(lines[0], _TXT_HEADER)
74
 
 
75
 
    def test_stats_save_to_callgrind(self):
76
 
        f = self._tempfile("callgrind")
77
 
        self.stats.save(f)
78
 
        lines = open(f).readlines()
79
 
        self.assertEqual(lines[0], "events: Ticks\n")
80
 
        f = bzrlib.osutils.pathjoin(self.test_dir, "callgrind.out.foo")
81
 
        self.stats.save(f)
82
 
        lines = open(f).readlines()
83
 
        self.assertEqual(lines[0], "events: Ticks\n")
 
60
    def _temppath(self, ext):
 
61
        return osutils.pathjoin(self.test_dir, "tmp_profile_data." + ext)
 
62
 
 
63
    def test_save_to_txt(self):
 
64
        path = self._temppath("txt")
 
65
        self.stats.save(path)
 
66
        with open(path) as f:
 
67
            lines = f.readlines()
 
68
            self.assertEqual(lines[0], _TXT_HEADER)
 
69
 
 
70
    def test_save_to_callgrind(self):
 
71
        path1 = self._temppath("callgrind")
 
72
        self.stats.save(path1)
 
73
        with open(path1) as f:
 
74
            self.assertEqual(f.readline(), "events: Ticks\n")
 
75
 
 
76
        path2 = osutils.pathjoin(self.test_dir, "callgrind.out.foo")
 
77
        self.stats.save(path2)
 
78
        with open(path2) as f:
 
79
            self.assertEqual(f.readline(), "events: Ticks\n")
 
80
 
84
81
        # Test explicit format nommination
85
 
        f2 = self._tempfile("txt")
86
 
        self.stats.save(f2, format="callgrind")
87
 
        lines2 = open(f2).readlines()
88
 
        self.assertEqual(lines2[0], "events: Ticks\n")
89
 
 
90
 
    def test_stats_save_to_pickle(self):
91
 
        f = self._tempfile("pkl")
92
 
        self.stats.save(f)
93
 
        data1 = cPickle.load(open(f))
94
 
        self.assertEqual(type(data1), bzrlib.lsprof.Stats)
 
82
        path3 = self._temppath("txt")
 
83
        self.stats.save(path3, format="callgrind")
 
84
        with open(path3) as f:
 
85
            self.assertEqual(f.readline(), "events: Ticks\n")
 
86
 
 
87
    def test_save_to_pickle(self):
 
88
        path = self._temppath("pkl")
 
89
        self.stats.save(path)
 
90
        with open(path, 'rb') as f:
 
91
            data1 = pickle.load(f)
 
92
            self.assertEqual(type(data1), lsprof.Stats)
 
93
 
 
94
    def test_sort(self):
 
95
        self.stats.sort()
 
96
        code_list = [d.inlinetime for d in self.stats.data]
 
97
        self.assertEqual(code_list, sorted(code_list, reverse=True))
 
98
 
 
99
    def test_sort_totaltime(self):
 
100
        self.stats.sort('totaltime')
 
101
        code_list = [d.totaltime for d in self.stats.data]
 
102
        self.assertEqual(code_list, sorted(code_list, reverse=True))
 
103
 
 
104
    def test_sort_code(self):
 
105
        """Cannot sort by code object would need to get filename etc."""
 
106
        self.assertRaises(ValueError, self.stats.sort, 'code')
95
107
 
96
108
 
97
109
class TestBzrProfiler(tests.TestCase):
98
110
 
99
 
    _test_needs_features = [LSProfFeature]
 
111
    _test_needs_features = [features.lsprof_feature]
100
112
 
101
113
    def test_start_call_stuff_stop(self):
102
 
        profiler = bzrlib.lsprof.BzrProfiler()
 
114
        profiler = lsprof.BzrProfiler()
103
115
        profiler.start()
104
116
        try:
105
117
            def a_function():
111
123
        lines = [str(data) for data in stats.data]
112
124
        lines = [line for line in lines if 'a_function' in line]
113
125
        self.assertLength(1, lines)
 
126
 
 
127
    def test_block_0(self):
 
128
        # When profiler_block is 0, reentrant profile requests fail.
 
129
        self.overrideAttr(lsprof.BzrProfiler, 'profiler_block', 0)
 
130
        inner_calls = []
 
131
        def inner():
 
132
            profiler = lsprof.BzrProfiler()
 
133
            self.assertRaises(errors.BzrError, profiler.start)
 
134
            inner_calls.append(True)
 
135
        lsprof.profile(inner)
 
136
        self.assertLength(1, inner_calls)
 
137
 
 
138
    def test_block_1(self):
 
139
        # When profiler_block is 1, concurrent profiles serialise.
 
140
        # This is tested by manually acquiring the profiler lock, then
 
141
        # starting a thread that tries to profile, and releasing the lock.
 
142
        # We know due to test_block_0 that two profiles at once hit the lock,
 
143
        # so while this isn't perfect (we'd want a callback on the lock being
 
144
        # entered to allow lockstep evaluation of the actions), its good enough
 
145
        # to be confident regressions would be caught. Alternatively, if this
 
146
        # is flakey, a fake Lock object can be used to trace the calls made.
 
147
        calls = []
 
148
        def profiled():
 
149
            calls.append('profiled')
 
150
        def do_profile():
 
151
            lsprof.profile(profiled)
 
152
            calls.append('after_profiled')
 
153
        thread = threading.Thread(target=do_profile)
 
154
        lsprof.BzrProfiler.profiler_lock.acquire()
 
155
        try:
 
156
            try:
 
157
                thread.start()
 
158
            finally:
 
159
                lsprof.BzrProfiler.profiler_lock.release()
 
160
        finally:
 
161
            thread.join()
 
162
        self.assertLength(2, calls)