~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_lsprof.py

  • Committer: Robert Collins
  • Date: 2010-07-04 06:22:11 UTC
  • mto: This revision was merged to the branch mainline in revision 5332.
  • Revision ID: robertc@robertcollins.net-20100704062211-tk9hw6bnsn5x47fm
``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
profiles when concurrent profile requests are made. Instead the profile
requests will be serialised. Reentrant requests will now deadlock.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
import cPickle
21
21
import os
 
22
import threading
22
23
 
23
24
import bzrlib
24
 
from bzrlib import tests
 
25
from bzrlib import errors, tests
25
26
 
26
27
 
27
28
class _LSProfFeature(tests.Feature):
111
112
        lines = [str(data) for data in stats.data]
112
113
        lines = [line for line in lines if 'a_function' in line]
113
114
        self.assertLength(1, lines)
 
115
 
 
116
    def test_block_0(self):
 
117
        # When profiler_block is 0, reentrant profile requests fail.
 
118
        self.overrideAttr(bzrlib.lsprof.BzrProfiler, 'profiler_block', 0)
 
119
        inner_calls = []
 
120
        def inner():
 
121
            profiler = bzrlib.lsprof.BzrProfiler()
 
122
            self.assertRaises(errors.BzrError, profiler.start)
 
123
            inner_calls.append(True)
 
124
        bzrlib.lsprof.profile(inner)
 
125
        self.assertLength(1, inner_calls)
 
126
 
 
127
    def test_block_1(self):
 
128
        # When profiler_block is 1, concurrent profiles serialise.
 
129
        # This is tested by manually acquiring the profiler lock, then
 
130
        # starting a thread that tries to profile, and releasing the lock. 
 
131
        # We know due to test_block_0 that two profiles at once hit the lock,
 
132
        # so while this isn't perfect (we'd want a callback on the lock being
 
133
        # entered to allow lockstep evaluation of the actions), its good enough
 
134
        # to be confident regressions would be caught. Alternatively, if this
 
135
        # is flakey, a fake Lock object can be used to trace the calls made.
 
136
        calls = []
 
137
        def profiled():
 
138
            calls.append('profiled')
 
139
        def do_profile():
 
140
            bzrlib.lsprof.profile(profiled)
 
141
            calls.append('after_profiled')
 
142
        thread = threading.Thread(target=do_profile)
 
143
        bzrlib.lsprof.BzrProfiler.profiler_lock.acquire()
 
144
        try:
 
145
            try:
 
146
                thread.start()
 
147
            finally:
 
148
                bzrlib.lsprof.BzrProfiler.profiler_lock.release()
 
149
        finally:
 
150
            thread.join()
 
151
        self.assertLength(2, calls)