1From 0dedc1c573ddc4e87475eb03c64555cd54a72e92 Mon Sep 17 00:00:00 2001 2From: Trevor Gamblin <trevor.gamblin@windriver.com> 3Date: Mon, 7 Jun 2021 09:40:20 -0400 4Subject: [PATCH] Fix imports for tests 5 6Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com> 7--- 8 tests/test_asyncio.py | 2 +- 9 tests/test_asyncio_context_vars.py | 2 +- 10 tests/test_functionality.py | 2 +- 11 tests/test_gevent.py | 2 +- 12 tests/test_hooks.py | 2 +- 13 tests/test_tags.py | 2 +- 14 6 files changed, 6 insertions(+), 6 deletions(-) 15 16--- a/tests/test_asyncio.py 17+++ b/tests/test_asyncio.py 18@@ -2,7 +2,7 @@ import unittest 19 import yappi 20 import asyncio 21 import threading 22-from utils import YappiUnitTestCase, find_stat_by_name, burn_cpu, burn_io 23+from .utils import YappiUnitTestCase, find_stat_by_name, burn_cpu, burn_io 24 25 26 @asyncio.coroutine 27--- a/tests/test_asyncio_context_vars.py 28+++ b/tests/test_asyncio_context_vars.py 29@@ -5,7 +5,7 @@ import contextvars 30 import functools 31 import time 32 import os 33-import utils 34+import tests.utils as utils 35 import yappi 36 37 async_context_id = contextvars.ContextVar('async_context_id') 38--- a/tests/test_functionality.py 39+++ b/tests/test_functionality.py 40@@ -1,1916 +1,1916 @@ 41-import os 42-import sys 43-import time 44-import threading 45-import unittest 46-import yappi 47-import _yappi 48-import utils 49-import multiprocessing # added to fix http://bugs.python.org/issue15881 for > Py2.6 50-import subprocess 51- 52-_counter = 0 53- 54- 55-class BasicUsage(utils.YappiUnitTestCase): 56- 57- def test_callback_function_int_return_overflow(self): 58- # this test is just here to check if any errors are generated, as the err 59- # is printed in C side, I did not include it here. THere are ways to test 60- # this deterministically, I did not bother 61- import ctypes 62- 63- def _unsigned_overflow_margin(): 64- return 2**(ctypes.sizeof(ctypes.c_void_p) * 8) - 1 65- 66- def foo(): 67- pass 68- 69- #with utils.captured_output() as (out, err): 70- yappi.set_context_id_callback(_unsigned_overflow_margin) 71- yappi.set_tag_callback(_unsigned_overflow_margin) 72- yappi.start() 73- foo() 74- 75- def test_issue60(self): 76- 77- def foo(): 78- buf = bytearray() 79- buf += b't' * 200 80- view = memoryview(buf)[10:] 81- view = view.tobytes() 82- del buf[:10] # this throws exception 83- return view 84- 85- yappi.start(builtins=True) 86- foo() 87- self.assertTrue( 88- len( 89- yappi.get_func_stats( 90- filter_callback=lambda x: yappi. 91- func_matches(x, [memoryview.tobytes]) 92- ) 93- ) > 0 94- ) 95- yappi.stop() 96- 97- def test_issue54(self): 98- 99- def _tag_cbk(): 100- global _counter 101- _counter += 1 102- return _counter 103- 104- def a(): 105- pass 106- 107- def b(): 108- pass 109- 110- yappi.set_tag_callback(_tag_cbk) 111- yappi.start() 112- a() 113- a() 114- a() 115- yappi.stop() 116- stats = yappi.get_func_stats() 117- self.assertEqual(stats.pop().ncall, 3) # aggregated if no tag is given 118- stats = yappi.get_func_stats(tag=1) 119- 120- for i in range(1, 3): 121- stats = yappi.get_func_stats(tag=i) 122- stats = yappi.get_func_stats( 123- tag=i, filter_callback=lambda x: yappi.func_matches(x, [a]) 124- ) 125- 126- stat = stats.pop() 127- self.assertEqual(stat.ncall, 1) 128- 129- yappi.set_tag_callback(None) 130- yappi.clear_stats() 131- yappi.start() 132- b() 133- b() 134- stats = yappi.get_func_stats() 135- self.assertEqual(len(stats), 1) 136- stat = stats.pop() 137- self.assertEqual(stat.ncall, 2) 138- 139- def test_filter(self): 140- 141- def a(): 142- pass 143- 144- def b(): 145- a() 146- 147- def c(): 148- b() 149- 150- _TCOUNT = 5 151- 152- ts = [] 153- yappi.start() 154- for i in range(_TCOUNT): 155- t = threading.Thread(target=c) 156- t.start() 157- ts.append(t) 158- 159- for t in ts: 160- t.join() 161- 162- yappi.stop() 163- 164- ctx_ids = [] 165- for tstat in yappi.get_thread_stats(): 166- if tstat.name == '_MainThread': 167- main_ctx_id = tstat.id 168- else: 169- ctx_ids.append(tstat.id) 170- 171- fstats = yappi.get_func_stats(filter={"ctx_id": 9}) 172- self.assertTrue(fstats.empty()) 173- fstats = yappi.get_func_stats( 174- filter={ 175- "ctx_id": main_ctx_id, 176- "name": "c" 177- } 178- ) # main thread 179- self.assertTrue(fstats.empty()) 180- 181- for i in ctx_ids: 182- fstats = yappi.get_func_stats( 183- filter={ 184- "ctx_id": i, 185- "name": "a", 186- "ncall": 1 187- } 188- ) 189- self.assertEqual(fstats.pop().ncall, 1) 190- fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "b"}) 191- self.assertEqual(fstats.pop().ncall, 1) 192- fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "c"}) 193- self.assertEqual(fstats.pop().ncall, 1) 194- 195- yappi.clear_stats() 196- yappi.start(builtins=True) 197- time.sleep(0.1) 198- yappi.stop() 199- fstats = yappi.get_func_stats(filter={"module": "time"}) 200- self.assertEqual(len(fstats), 1) 201- 202- # invalid filters` 203- self.assertRaises( 204- Exception, yappi.get_func_stats, filter={'tag': "sss"} 205- ) 206- self.assertRaises( 207- Exception, yappi.get_func_stats, filter={'ctx_id': "None"} 208- ) 209- 210- def test_filter_callback(self): 211- 212- def a(): 213- time.sleep(0.1) 214- 215- def b(): 216- a() 217- 218- def c(): 219- pass 220- 221- def d(): 222- pass 223- 224- yappi.set_clock_type("wall") 225- yappi.start(builtins=True) 226- a() 227- b() 228- c() 229- d() 230- stats = yappi.get_func_stats( 231- filter_callback=lambda x: yappi.func_matches(x, [a, b]) 232- ) 233- #stats.print_all() 234- r1 = ''' 235- tests/test_functionality.py:98 a 2 0.000000 0.200350 0.100175 236- tests/test_functionality.py:101 b 1 0.000000 0.120000 0.100197 237- ''' 238- self.assert_traces_almost_equal(r1, stats) 239- self.assertEqual(len(stats), 2) 240- stats = yappi.get_func_stats( 241- filter_callback=lambda x: yappi. 242- module_matches(x, [sys.modules[__name__]]) 243- ) 244- r1 = ''' 245- tests/test_functionality.py:98 a 2 0.000000 0.230130 0.115065 246- tests/test_functionality.py:101 b 1 0.000000 0.120000 0.109011 247- tests/test_functionality.py:104 c 1 0.000000 0.000002 0.000002 248- tests/test_functionality.py:107 d 1 0.000000 0.000001 0.000001 249- ''' 250- self.assert_traces_almost_equal(r1, stats) 251- self.assertEqual(len(stats), 4) 252- 253- stats = yappi.get_func_stats( 254- filter_callback=lambda x: yappi.func_matches(x, [time.sleep]) 255- ) 256- self.assertEqual(len(stats), 1) 257- r1 = ''' 258- time.sleep 2 0.206804 0.220000 0.103402 259- ''' 260- self.assert_traces_almost_equal(r1, stats) 261- 262- def test_print_formatting(self): 263- 264- def a(): 265- pass 266- 267- def b(): 268- a() 269- 270- func_cols = { 271- 1: ("name", 48), 272- 0: ("ncall", 5), 273- 2: ("tsub", 8), 274- } 275- thread_cols = { 276- 1: ("name", 48), 277- 0: ("ttot", 8), 278- } 279- 280- yappi.start() 281- a() 282- b() 283- yappi.stop() 284- fs = yappi.get_func_stats() 285- cs = fs[1].children 286- ts = yappi.get_thread_stats() 287- #fs.print_all(out=sys.stderr, columns={1:("name", 70), }) 288- #cs.print_all(out=sys.stderr, columns=func_cols) 289- #ts.print_all(out=sys.stderr, columns=thread_cols) 290- #cs.print_all(out=sys.stderr, columns={}) 291- 292- self.assertRaises( 293- yappi.YappiError, fs.print_all, columns={1: ("namee", 9)} 294- ) 295- self.assertRaises( 296- yappi.YappiError, cs.print_all, columns={1: ("dd", 0)} 297- ) 298- self.assertRaises( 299- yappi.YappiError, ts.print_all, columns={1: ("tidd", 0)} 300- ) 301- 302- def test_get_clock(self): 303- yappi.set_clock_type('cpu') 304- self.assertEqual('cpu', yappi.get_clock_type()) 305- clock_info = yappi.get_clock_info() 306- self.assertTrue('api' in clock_info) 307- self.assertTrue('resolution' in clock_info) 308- 309- yappi.set_clock_type('wall') 310- self.assertEqual('wall', yappi.get_clock_type()) 311- 312- t0 = yappi.get_clock_time() 313- time.sleep(0.1) 314- duration = yappi.get_clock_time() - t0 315- self.assertTrue(0.05 < duration < 0.3) 316- 317- def test_profile_decorator(self): 318- 319- def aggregate(func, stats): 320- fname = "tests/%s.profile" % (func.__name__) 321- try: 322- stats.add(fname) 323- except IOError: 324- pass 325- stats.save(fname) 326- raise Exception("messing around") 327- 328- @yappi.profile(return_callback=aggregate) 329- def a(x, y): 330- if x + y == 25: 331- raise Exception("") 332- return x + y 333- 334- def b(): 335- pass 336- 337- try: 338- os.remove( 339- "tests/a.profile" 340- ) # remove the one from prev test, if available 341- except: 342- pass 343- 344- # global profile is on to mess things up 345- yappi.start() 346- b() 347- 348- # assert functionality and call function at same time 349- try: 350- self.assertEqual(a(1, 2), 3) 351- except: 352- pass 353- try: 354- self.assertEqual(a(2, 5), 7) 355- except: 356- pass 357- try: 358- a(4, 21) 359- except: 360- pass 361- stats = yappi.get_func_stats().add("tests/a.profile") 362- fsa = utils.find_stat_by_name(stats, 'a') 363- self.assertEqual(fsa.ncall, 3) 364- self.assertEqual(len(stats), 1) # b() should be cleared out. 365- 366- @yappi.profile(return_callback=aggregate) 367- def count_down_rec(n): 368- if n == 0: 369- return 370- count_down_rec(n - 1) 371- 372- try: 373- os.remove( 374- "tests/count_down_rec.profile" 375- ) # remove the one from prev test, if available 376- except: 377- pass 378- 379- try: 380- count_down_rec(4) 381- except: 382- pass 383- try: 384- count_down_rec(3) 385- except: 386- pass 387- 388- stats = yappi.YFuncStats("tests/count_down_rec.profile") 389- fsrec = utils.find_stat_by_name(stats, 'count_down_rec') 390- self.assertEqual(fsrec.ncall, 9) 391- self.assertEqual(fsrec.nactualcall, 2) 392- 393- def test_strip_dirs(self): 394- 395- def a(): 396- pass 397- 398- stats = utils.run_and_get_func_stats(a, ) 399- stats.strip_dirs() 400- fsa = utils.find_stat_by_name(stats, "a") 401- self.assertEqual(fsa.module, os.path.basename(fsa.module)) 402- 403- @unittest.skipIf(os.name == "nt", "do not run on Windows") 404- def test_run_as_script(self): 405- import re 406- p = subprocess.Popen( 407- ['yappi', os.path.join('./tests', 'run_as_script.py')], 408- stdout=subprocess.PIPE 409- ) 410- out, err = p.communicate() 411- self.assertEqual(p.returncode, 0) 412- func_stats, thread_stats = re.split( 413- b'name\\s+id\\s+tid\\s+ttot\\s+scnt\\s*\n', out 414- ) 415- self.assertTrue(b'FancyThread' in thread_stats) 416- 417- def test_yappi_overhead(self): 418- LOOP_COUNT = 100000 419- 420- def a(): 421- pass 422- 423- def b(): 424- for i in range(LOOP_COUNT): 425- a() 426- 427- t0 = time.time() 428- yappi.start() 429- b() 430- yappi.stop() 431- time_with_yappi = time.time() - t0 432- t0 = time.time() 433- b() 434- time_without_yappi = time.time() - t0 435- if time_without_yappi == 0: 436- time_without_yappi = 0.000001 437- 438- # in latest v0.82, I calculated this as close to "7.0" in my machine. 439- # however, %83 of this overhead is coming from tickcount(). The other %17 440- # seems to have been evenly distributed to the internal bookkeeping 441- # structures/algorithms which seems acceptable. Note that our test only 442- # tests one function being profiled at-a-time in a short interval. 443- # profiling high number of functions in a small time 444- # is a different beast, (which is pretty unlikely in most applications) 445- # So as a conclusion: I cannot see any optimization window for Yappi that 446- # is worth implementing as we will only optimize %17 of the time. 447- sys.stderr.write("\r\nYappi puts %0.1f times overhead to the profiled application in average.\r\n" % \ 448- (time_with_yappi / time_without_yappi)) 449- 450- def test_clear_stats_while_running(self): 451- 452- def a(): 453- pass 454- 455- yappi.start() 456- a() 457- yappi.clear_stats() 458- a() 459- stats = yappi.get_func_stats() 460- fsa = utils.find_stat_by_name(stats, 'a') 461- self.assertEqual(fsa.ncall, 1) 462- 463- def test_generator(self): 464- 465- def _gen(n): 466- while (n > 0): 467- yield n 468- n -= 1 469- 470- yappi.start() 471- for x in _gen(5): 472- pass 473- self.assertTrue( 474- yappi.convert2pstats(yappi.get_func_stats()) is not None 475- ) 476- 477- def test_slice_child_stats_and_strip_dirs(self): 478- 479- def b(): 480- for i in range(10000000): 481- pass 482- 483- def a(): 484- b() 485- 486- yappi.start(builtins=True) 487- a() 488- stats = yappi.get_func_stats() 489- fsa = utils.find_stat_by_name(stats, 'a') 490- fsb = utils.find_stat_by_name(stats, 'b') 491- self.assertTrue(fsa.children[0:1] is not None) 492- prev_afullname = fsa.full_name 493- prev_bchildfullname = fsa.children[fsb].full_name 494- stats.strip_dirs() 495- self.assertTrue(len(prev_afullname) > len(fsa.full_name)) 496- self.assertTrue( 497- len(prev_bchildfullname) > len(fsa.children[fsb].full_name) 498- ) 499- 500- def test_children_stat_functions(self): 501- _timings = {"a_1": 5, "b_1": 3, "c_1": 1} 502- _yappi._set_test_timings(_timings) 503- 504- def b(): 505- pass 506- 507- def c(): 508- pass 509- 510- def a(): 511- b() 512- c() 513- 514- yappi.start() 515- a() 516- b() # non-child call 517- c() # non-child call 518- stats = yappi.get_func_stats() 519- fsa = utils.find_stat_by_name(stats, 'a') 520- childs_of_a = fsa.children.get().sort("tavg", "desc") 521- prev_item = None 522- for item in childs_of_a: 523- if prev_item: 524- self.assertTrue(prev_item.tavg > item.tavg) 525- prev_item = item 526- childs_of_a.sort("name", "desc") 527- prev_item = None 528- for item in childs_of_a: 529- if prev_item: 530- self.assertTrue(prev_item.name > item.name) 531- prev_item = item 532- childs_of_a.clear() 533- self.assertTrue(childs_of_a.empty()) 534- 535- def test_no_stats_different_clock_type_load(self): 536- 537- def a(): 538- pass 539- 540- yappi.start() 541- a() 542- yappi.stop() 543- yappi.get_func_stats().save("tests/ystats1.ys") 544- yappi.clear_stats() 545- yappi.set_clock_type("WALL") 546- yappi.start() 547- yappi.stop() 548- stats = yappi.get_func_stats().add("tests/ystats1.ys") 549- fsa = utils.find_stat_by_name(stats, 'a') 550- self.assertTrue(fsa is not None) 551- 552- def test_subsequent_profile(self): 553- _timings = {"a_1": 1, "b_1": 1} 554- _yappi._set_test_timings(_timings) 555- 556- def a(): 557- pass 558- 559- def b(): 560- pass 561- 562- yappi.start() 563- a() 564- yappi.stop() 565- yappi.start() 566- b() 567- yappi.stop() 568- stats = yappi.get_func_stats() 569- fsa = utils.find_stat_by_name(stats, 'a') 570- fsb = utils.find_stat_by_name(stats, 'b') 571- self.assertTrue(fsa is not None) 572- self.assertTrue(fsb is not None) 573- self.assertEqual(fsa.ttot, 1) 574- self.assertEqual(fsb.ttot, 1) 575- 576- def test_lambda(self): 577- f = lambda: time.sleep(0.3) 578- yappi.set_clock_type("wall") 579- yappi.start() 580- f() 581- stats = yappi.get_func_stats() 582- fsa = utils.find_stat_by_name(stats, '<lambda>') 583- self.assertTrue(fsa.ttot > 0.1) 584- 585- def test_module_stress(self): 586- self.assertEqual(yappi.is_running(), False) 587- 588- yappi.start() 589- yappi.clear_stats() 590- self.assertRaises(_yappi.error, yappi.set_clock_type, "wall") 591- 592- yappi.stop() 593- yappi.clear_stats() 594- yappi.set_clock_type("cpu") 595- self.assertRaises(yappi.YappiError, yappi.set_clock_type, "dummy") 596- self.assertEqual(yappi.is_running(), False) 597- yappi.clear_stats() 598- yappi.clear_stats() 599- 600- def test_stat_sorting(self): 601- _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1} 602- _yappi._set_test_timings(_timings) 603- 604- self._ncall = 1 605- 606- def a(): 607- b() 608- 609- def b(): 610- if self._ncall == 2: 611- return 612- self._ncall += 1 613- a() 614- 615- stats = utils.run_and_get_func_stats(a) 616- stats = stats.sort("totaltime", "desc") 617- prev_stat = None 618- for stat in stats: 619- if prev_stat: 620- self.assertTrue(prev_stat.ttot >= stat.ttot) 621- prev_stat = stat 622- stats = stats.sort("totaltime", "asc") 623- prev_stat = None 624- for stat in stats: 625- if prev_stat: 626- self.assertTrue(prev_stat.ttot <= stat.ttot) 627- prev_stat = stat 628- stats = stats.sort("avgtime", "asc") 629- prev_stat = None 630- for stat in stats: 631- if prev_stat: 632- self.assertTrue(prev_stat.tavg <= stat.tavg) 633- prev_stat = stat 634- stats = stats.sort("name", "asc") 635- prev_stat = None 636- for stat in stats: 637- if prev_stat: 638- self.assertTrue(prev_stat.name <= stat.name) 639- prev_stat = stat 640- stats = stats.sort("subtime", "asc") 641- prev_stat = None 642- for stat in stats: 643- if prev_stat: 644- self.assertTrue(prev_stat.tsub <= stat.tsub) 645- prev_stat = stat 646- 647- self.assertRaises( 648- yappi.YappiError, stats.sort, "invalid_func_sorttype_arg" 649- ) 650- self.assertRaises( 651- yappi.YappiError, stats.sort, "totaltime", 652- "invalid_func_sortorder_arg" 653- ) 654- 655- def test_start_flags(self): 656- self.assertEqual(_yappi._get_start_flags(), None) 657- yappi.start() 658- 659- def a(): 660- pass 661- 662- a() 663- self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0) 664- self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1) 665- self.assertEqual(len(yappi.get_thread_stats()), 1) 666- 667- def test_builtin_profiling(self): 668- 669- def a(): 670- time.sleep(0.4) # is a builtin function 671- 672- yappi.set_clock_type('wall') 673- 674- yappi.start(builtins=True) 675- a() 676- stats = yappi.get_func_stats() 677- fsa = utils.find_stat_by_name(stats, 'sleep') 678- self.assertTrue(fsa is not None) 679- self.assertTrue(fsa.ttot > 0.3) 680- yappi.stop() 681- yappi.clear_stats() 682- 683- def a(): 684- pass 685- 686- yappi.start() 687- t = threading.Thread(target=a) 688- t.start() 689- t.join() 690- stats = yappi.get_func_stats() 691- 692- def test_singlethread_profiling(self): 693- yappi.set_clock_type('wall') 694- 695- def a(): 696- time.sleep(0.2) 697- 698- class Worker1(threading.Thread): 699- 700- def a(self): 701- time.sleep(0.3) 702- 703- def run(self): 704- self.a() 705- 706- yappi.start(profile_threads=False) 707- 708- c = Worker1() 709- c.start() 710- c.join() 711- a() 712- stats = yappi.get_func_stats() 713- fsa1 = utils.find_stat_by_name(stats, 'Worker1.a') 714- fsa2 = utils.find_stat_by_name(stats, 'a') 715- self.assertTrue(fsa1 is None) 716- self.assertTrue(fsa2 is not None) 717- self.assertTrue(fsa2.ttot > 0.1) 718- 719- def test_run(self): 720- 721- def profiled(): 722- pass 723- 724- yappi.clear_stats() 725- try: 726- with yappi.run(): 727- profiled() 728- stats = yappi.get_func_stats() 729- finally: 730- yappi.clear_stats() 731- 732- self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled')) 733- 734- def test_run_recursive(self): 735- 736- def profiled(): 737- pass 738- 739- def not_profiled(): 740- pass 741- 742- yappi.clear_stats() 743- try: 744- with yappi.run(): 745- with yappi.run(): 746- profiled() 747- # Profiling stopped here 748- not_profiled() 749- stats = yappi.get_func_stats() 750- finally: 751- yappi.clear_stats() 752- 753- self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled')) 754- self.assertIsNone(utils.find_stat_by_name(stats, 'not_profiled')) 755- 756- 757-class StatSaveScenarios(utils.YappiUnitTestCase): 758- 759- def test_pstats_conversion(self): 760- 761- def pstat_id(fs): 762- return (fs.module, fs.lineno, fs.name) 763- 764- def a(): 765- d() 766- 767- def b(): 768- d() 769- 770- def c(): 771- pass 772- 773- def d(): 774- pass 775- 776- _timings = {"a_1": 12, "b_1": 7, "c_1": 5, "d_1": 2} 777- _yappi._set_test_timings(_timings) 778- stats = utils.run_and_get_func_stats(a, ) 779- stats.strip_dirs() 780- stats.save("tests/a1.pstats", type="pstat") 781- fsa_pid = pstat_id(utils.find_stat_by_name(stats, "a")) 782- fsd_pid = pstat_id(utils.find_stat_by_name(stats, "d")) 783- yappi.clear_stats() 784- _yappi._set_test_timings(_timings) 785- stats = utils.run_and_get_func_stats(a, ) 786- stats.strip_dirs() 787- stats.save("tests/a2.pstats", type="pstat") 788- yappi.clear_stats() 789- _yappi._set_test_timings(_timings) 790- stats = utils.run_and_get_func_stats(b, ) 791- stats.strip_dirs() 792- stats.save("tests/b1.pstats", type="pstat") 793- fsb_pid = pstat_id(utils.find_stat_by_name(stats, "b")) 794- yappi.clear_stats() 795- _yappi._set_test_timings(_timings) 796- stats = utils.run_and_get_func_stats(c, ) 797- stats.strip_dirs() 798- stats.save("tests/c1.pstats", type="pstat") 799- fsc_pid = pstat_id(utils.find_stat_by_name(stats, "c")) 800- 801- # merge saved stats and check pstats values are correct 802- import pstats 803- p = pstats.Stats( 804- 'tests/a1.pstats', 'tests/a2.pstats', 'tests/b1.pstats', 805- 'tests/c1.pstats' 806- ) 807- p.strip_dirs() 808- # ct = ttot, tt = tsub 809- (cc, nc, tt, ct, callers) = p.stats[fsa_pid] 810- self.assertEqual(cc, nc, 2) 811- self.assertEqual(tt, 20) 812- self.assertEqual(ct, 24) 813- (cc, nc, tt, ct, callers) = p.stats[fsd_pid] 814- self.assertEqual(cc, nc, 3) 815- self.assertEqual(tt, 6) 816- self.assertEqual(ct, 6) 817- self.assertEqual(len(callers), 2) 818- (cc, nc, tt, ct) = callers[fsa_pid] 819- self.assertEqual(cc, nc, 2) 820- self.assertEqual(tt, 4) 821- self.assertEqual(ct, 4) 822- (cc, nc, tt, ct) = callers[fsb_pid] 823- self.assertEqual(cc, nc, 1) 824- self.assertEqual(tt, 2) 825- self.assertEqual(ct, 2) 826- 827- def test_merge_stats(self): 828- _timings = { 829- "a_1": 15, 830- "b_1": 14, 831- "c_1": 12, 832- "d_1": 10, 833- "e_1": 9, 834- "f_1": 7, 835- "g_1": 6, 836- "h_1": 5, 837- "i_1": 1 838- } 839- _yappi._set_test_timings(_timings) 840- 841- def a(): 842- b() 843- 844- def b(): 845- c() 846- 847- def c(): 848- d() 849- 850- def d(): 851- e() 852- 853- def e(): 854- f() 855- 856- def f(): 857- g() 858- 859- def g(): 860- h() 861- 862- def h(): 863- i() 864- 865- def i(): 866- pass 867- 868- yappi.start() 869- a() 870- a() 871- yappi.stop() 872- stats = yappi.get_func_stats() 873- self.assertRaises( 874- NotImplementedError, stats.save, "", "INVALID_SAVE_TYPE" 875- ) 876- stats.save("tests/ystats2.ys") 877- yappi.clear_stats() 878- _yappi._set_test_timings(_timings) 879- yappi.start() 880- a() 881- stats = yappi.get_func_stats().add("tests/ystats2.ys") 882- fsa = utils.find_stat_by_name(stats, "a") 883- fsb = utils.find_stat_by_name(stats, "b") 884- fsc = utils.find_stat_by_name(stats, "c") 885- fsd = utils.find_stat_by_name(stats, "d") 886- fse = utils.find_stat_by_name(stats, "e") 887- fsf = utils.find_stat_by_name(stats, "f") 888- fsg = utils.find_stat_by_name(stats, "g") 889- fsh = utils.find_stat_by_name(stats, "h") 890- fsi = utils.find_stat_by_name(stats, "i") 891- self.assertEqual(fsa.ttot, 45) 892- self.assertEqual(fsa.ncall, 3) 893- self.assertEqual(fsa.nactualcall, 3) 894- self.assertEqual(fsa.tsub, 3) 895- self.assertEqual(fsa.children[fsb].ttot, fsb.ttot) 896- self.assertEqual(fsa.children[fsb].tsub, fsb.tsub) 897- self.assertEqual(fsb.children[fsc].ttot, fsc.ttot) 898- self.assertEqual(fsb.children[fsc].tsub, fsc.tsub) 899- self.assertEqual(fsc.tsub, 6) 900- self.assertEqual(fsc.children[fsd].ttot, fsd.ttot) 901- self.assertEqual(fsc.children[fsd].tsub, fsd.tsub) 902- self.assertEqual(fsd.children[fse].ttot, fse.ttot) 903- self.assertEqual(fsd.children[fse].tsub, fse.tsub) 904- self.assertEqual(fse.children[fsf].ttot, fsf.ttot) 905- self.assertEqual(fse.children[fsf].tsub, fsf.tsub) 906- self.assertEqual(fsf.children[fsg].ttot, fsg.ttot) 907- self.assertEqual(fsf.children[fsg].tsub, fsg.tsub) 908- self.assertEqual(fsg.ttot, 18) 909- self.assertEqual(fsg.tsub, 3) 910- self.assertEqual(fsg.children[fsh].ttot, fsh.ttot) 911- self.assertEqual(fsg.children[fsh].tsub, fsh.tsub) 912- self.assertEqual(fsh.ttot, 15) 913- self.assertEqual(fsh.tsub, 12) 914- self.assertEqual(fsh.tavg, 5) 915- self.assertEqual(fsh.children[fsi].ttot, fsi.ttot) 916- self.assertEqual(fsh.children[fsi].tsub, fsi.tsub) 917- #stats.debug_print() 918- 919- def test_merge_multithreaded_stats(self): 920- import _yappi 921- timings = {"a_1": 2, "b_1": 1} 922- _yappi._set_test_timings(timings) 923- 924- def a(): 925- pass 926- 927- def b(): 928- pass 929- 930- yappi.start() 931- t = threading.Thread(target=a) 932- t.start() 933- t.join() 934- t = threading.Thread(target=b) 935- t.start() 936- t.join() 937- yappi.get_func_stats().save("tests/ystats1.ys") 938- yappi.clear_stats() 939- _yappi._set_test_timings(timings) 940- self.assertEqual(len(yappi.get_func_stats()), 0) 941- self.assertEqual(len(yappi.get_thread_stats()), 1) 942- t = threading.Thread(target=a) 943- t.start() 944- t.join() 945- 946- self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0) 947- self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1) 948- yappi.get_func_stats().save("tests/ystats2.ys") 949- 950- stats = yappi.YFuncStats([ 951- "tests/ystats1.ys", 952- "tests/ystats2.ys", 953- ]) 954- fsa = utils.find_stat_by_name(stats, "a") 955- fsb = utils.find_stat_by_name(stats, "b") 956- self.assertEqual(fsa.ncall, 2) 957- self.assertEqual(fsb.ncall, 1) 958- self.assertEqual(fsa.tsub, fsa.ttot, 4) 959- self.assertEqual(fsb.tsub, fsb.ttot, 1) 960- 961- def test_merge_load_different_clock_types(self): 962- yappi.start(builtins=True) 963- 964- def a(): 965- b() 966- 967- def b(): 968- c() 969- 970- def c(): 971- pass 972- 973- t = threading.Thread(target=a) 974- t.start() 975- t.join() 976- yappi.get_func_stats().sort("name", "asc").save("tests/ystats1.ys") 977- yappi.stop() 978- yappi.clear_stats() 979- yappi.start(builtins=False) 980- t = threading.Thread(target=a) 981- t.start() 982- t.join() 983- yappi.get_func_stats().save("tests/ystats2.ys") 984- yappi.stop() 985- self.assertRaises(_yappi.error, yappi.set_clock_type, "wall") 986- yappi.clear_stats() 987- yappi.set_clock_type("wall") 988- yappi.start() 989- t = threading.Thread(target=a) 990- t.start() 991- t.join() 992- yappi.get_func_stats().save("tests/ystats3.ys") 993- self.assertRaises( 994- yappi.YappiError, 995- yappi.YFuncStats().add("tests/ystats1.ys").add, "tests/ystats3.ys" 996- ) 997- stats = yappi.YFuncStats(["tests/ystats1.ys", 998- "tests/ystats2.ys"]).sort("name") 999- fsa = utils.find_stat_by_name(stats, "a") 1000- fsb = utils.find_stat_by_name(stats, "b") 1001- fsc = utils.find_stat_by_name(stats, "c") 1002- self.assertEqual(fsa.ncall, 2) 1003- self.assertEqual(fsa.ncall, fsb.ncall, fsc.ncall) 1004- 1005- def test_merge_aabab_aabbc(self): 1006- _timings = { 1007- "a_1": 15, 1008- "a_2": 14, 1009- "b_1": 12, 1010- "a_3": 10, 1011- "b_2": 9, 1012- "c_1": 4 1013- } 1014- _yappi._set_test_timings(_timings) 1015- 1016- def a(): 1017- if self._ncall == 1: 1018- self._ncall += 1 1019- a() 1020- elif self._ncall == 5: 1021- self._ncall += 1 1022- a() 1023- else: 1024- b() 1025- 1026- def b(): 1027- if self._ncall == 2: 1028- self._ncall += 1 1029- a() 1030- elif self._ncall == 6: 1031- self._ncall += 1 1032- b() 1033- elif self._ncall == 7: 1034- c() 1035- else: 1036- return 1037- 1038- def c(): 1039- pass 1040- 1041- self._ncall = 1 1042- stats = utils.run_and_get_func_stats(a, ) 1043- stats.save("tests/ystats1.ys") 1044- yappi.clear_stats() 1045- _yappi._set_test_timings(_timings) 1046- #stats.print_all() 1047- 1048- self._ncall = 5 1049- stats = utils.run_and_get_func_stats(a, ) 1050- stats.save("tests/ystats2.ys") 1051- 1052- #stats.print_all() 1053- 1054- def a(): # same name but another function(code object) 1055- pass 1056- 1057- yappi.start() 1058- a() 1059- stats = yappi.get_func_stats().add( 1060- ["tests/ystats1.ys", "tests/ystats2.ys"] 1061- ) 1062- #stats.print_all() 1063- self.assertEqual(len(stats), 4) 1064- 1065- fsa = None 1066- for stat in stats: 1067- if stat.name == "a" and stat.ttot == 45: 1068- fsa = stat 1069- break 1070- self.assertTrue(fsa is not None) 1071- 1072- self.assertEqual(fsa.ncall, 7) 1073- self.assertEqual(fsa.nactualcall, 3) 1074- self.assertEqual(fsa.ttot, 45) 1075- self.assertEqual(fsa.tsub, 10) 1076- fsb = utils.find_stat_by_name(stats, "b") 1077- fsc = utils.find_stat_by_name(stats, "c") 1078- self.assertEqual(fsb.ncall, 6) 1079- self.assertEqual(fsb.nactualcall, 3) 1080- self.assertEqual(fsb.ttot, 36) 1081- self.assertEqual(fsb.tsub, 27) 1082- self.assertEqual(fsb.tavg, 6) 1083- self.assertEqual(fsc.ttot, 8) 1084- self.assertEqual(fsc.tsub, 8) 1085- self.assertEqual(fsc.tavg, 4) 1086- self.assertEqual(fsc.nactualcall, fsc.ncall, 2) 1087- 1088- 1089-class MultithreadedScenarios(utils.YappiUnitTestCase): 1090- 1091- def test_issue_32(self): 1092- ''' 1093- Start yappi from different thread and we get Internal Error(15) as 1094- the current_ctx_id() called while enumerating the threads in start() 1095- and as it does not swap to the enumerated ThreadState* the THreadState_GetDict() 1096- returns wrong object and thus sets an invalid id for the _ctx structure. 1097- 1098- When this issue happens multiple Threads have same tid as the internal ts_ptr 1099- will be same for different contexts. So, let's see if that happens 1100- ''' 1101- 1102- def foo(): 1103- time.sleep(0.2) 1104- 1105- def bar(): 1106- time.sleep(0.1) 1107- 1108- def thread_func(): 1109- yappi.set_clock_type("wall") 1110- yappi.start() 1111- 1112- bar() 1113- 1114- t = threading.Thread(target=thread_func) 1115- t.start() 1116- t.join() 1117- 1118- foo() 1119- 1120- yappi.stop() 1121- 1122- thread_ids = set() 1123- for tstat in yappi.get_thread_stats(): 1124- self.assertTrue(tstat.tid not in thread_ids) 1125- thread_ids.add(tstat.tid) 1126- 1127- def test_subsequent_profile(self): 1128- WORKER_COUNT = 5 1129- 1130- def a(): 1131- pass 1132- 1133- def b(): 1134- pass 1135- 1136- def c(): 1137- pass 1138- 1139- _timings = { 1140- "a_1": 3, 1141- "b_1": 2, 1142- "c_1": 1, 1143- } 1144- 1145- yappi.start() 1146- 1147- def g(): 1148- pass 1149- 1150- g() 1151- yappi.stop() 1152- yappi.clear_stats() 1153- _yappi._set_test_timings(_timings) 1154- yappi.start() 1155- 1156- _dummy = [] 1157- for i in range(WORKER_COUNT): 1158- t = threading.Thread(target=a) 1159- t.start() 1160- t.join() 1161- for i in range(WORKER_COUNT): 1162- t = threading.Thread(target=b) 1163- t.start() 1164- _dummy.append(t) 1165- t.join() 1166- for i in range(WORKER_COUNT): 1167- t = threading.Thread(target=a) 1168- t.start() 1169- t.join() 1170- for i in range(WORKER_COUNT): 1171- t = threading.Thread(target=c) 1172- t.start() 1173- t.join() 1174- yappi.stop() 1175- yappi.start() 1176- 1177- def f(): 1178- pass 1179- 1180- f() 1181- stats = yappi.get_func_stats() 1182- fsa = utils.find_stat_by_name(stats, 'a') 1183- fsb = utils.find_stat_by_name(stats, 'b') 1184- fsc = utils.find_stat_by_name(stats, 'c') 1185- self.assertEqual(fsa.ncall, 10) 1186- self.assertEqual(fsb.ncall, 5) 1187- self.assertEqual(fsc.ncall, 5) 1188- self.assertEqual(fsa.ttot, fsa.tsub, 30) 1189- self.assertEqual(fsb.ttot, fsb.tsub, 10) 1190- self.assertEqual(fsc.ttot, fsc.tsub, 5) 1191- 1192- # MACOSx optimizes by only creating one worker thread 1193- self.assertTrue(len(yappi.get_thread_stats()) >= 2) 1194- 1195- def test_basic(self): 1196- yappi.set_clock_type('wall') 1197- 1198- def dummy(): 1199- pass 1200- 1201- def a(): 1202- time.sleep(0.2) 1203- 1204- class Worker1(threading.Thread): 1205- 1206- def a(self): 1207- time.sleep(0.3) 1208- 1209- def run(self): 1210- self.a() 1211- 1212- yappi.start(builtins=False, profile_threads=True) 1213- 1214- c = Worker1() 1215- c.start() 1216- c.join() 1217- a() 1218- stats = yappi.get_func_stats() 1219- fsa1 = utils.find_stat_by_name(stats, 'Worker1.a') 1220- fsa2 = utils.find_stat_by_name(stats, 'a') 1221- self.assertTrue(fsa1 is not None) 1222- self.assertTrue(fsa2 is not None) 1223- self.assertTrue(fsa1.ttot > 0.2) 1224- self.assertTrue(fsa2.ttot > 0.1) 1225- tstats = yappi.get_thread_stats() 1226- self.assertEqual(len(tstats), 2) 1227- tsa = utils.find_stat_by_name(tstats, 'Worker1') 1228- tsm = utils.find_stat_by_name(tstats, '_MainThread') 1229- dummy() # call dummy to force ctx name to be retrieved again. 1230- self.assertTrue(tsa is not None) 1231- # TODO: I put dummy() to fix below, remove the comments after a while. 1232- self.assertTrue( # FIX: I see this fails sometimes? 1233- tsm is not None, 1234- 'Could not find "_MainThread". Found: %s' % (', '.join(utils.get_stat_names(tstats)))) 1235- 1236- def test_ctx_stats(self): 1237- from threading import Thread 1238- DUMMY_WORKER_COUNT = 5 1239- yappi.start() 1240- 1241- class DummyThread(Thread): 1242- pass 1243- 1244- def dummy(): 1245- pass 1246- 1247- def dummy_worker(): 1248- pass 1249- 1250- for i in range(DUMMY_WORKER_COUNT): 1251- t = DummyThread(target=dummy_worker) 1252- t.start() 1253- t.join() 1254- yappi.stop() 1255- stats = yappi.get_thread_stats() 1256- tsa = utils.find_stat_by_name(stats, "DummyThread") 1257- self.assertTrue(tsa is not None) 1258- yappi.clear_stats() 1259- time.sleep(1.0) 1260- _timings = { 1261- "a_1": 6, 1262- "b_1": 5, 1263- "c_1": 3, 1264- "d_1": 1, 1265- "a_2": 4, 1266- "b_2": 3, 1267- "c_2": 2, 1268- "d_2": 1 1269- } 1270- _yappi._set_test_timings(_timings) 1271- 1272- class Thread1(Thread): 1273- pass 1274- 1275- class Thread2(Thread): 1276- pass 1277- 1278- def a(): 1279- b() 1280- 1281- def b(): 1282- c() 1283- 1284- def c(): 1285- d() 1286- 1287- def d(): 1288- time.sleep(0.6) 1289- 1290- yappi.set_clock_type("wall") 1291- yappi.start() 1292- t1 = Thread1(target=a) 1293- t1.start() 1294- t2 = Thread2(target=a) 1295- t2.start() 1296- t1.join() 1297- t2.join() 1298- stats = yappi.get_thread_stats() 1299- 1300- # the fist clear_stats clears the context table? 1301- tsa = utils.find_stat_by_name(stats, "DummyThread") 1302- self.assertTrue(tsa is None) 1303- 1304- tst1 = utils.find_stat_by_name(stats, "Thread1") 1305- tst2 = utils.find_stat_by_name(stats, "Thread2") 1306- tsmain = utils.find_stat_by_name(stats, "_MainThread") 1307- dummy() # call dummy to force ctx name to be retrieved again. 1308- self.assertTrue(len(stats) == 3) 1309- self.assertTrue(tst1 is not None) 1310- self.assertTrue(tst2 is not None) 1311- # TODO: I put dummy() to fix below, remove the comments after a while. 1312- self.assertTrue( # FIX: I see this fails sometimes 1313- tsmain is not None, 1314- 'Could not find "_MainThread". Found: %s' % (', '.join(utils.get_stat_names(stats)))) 1315- self.assertTrue(1.0 > tst2.ttot >= 0.5) 1316- self.assertTrue(1.0 > tst1.ttot >= 0.5) 1317- 1318- # test sorting of the ctx stats 1319- stats = stats.sort("totaltime", "desc") 1320- prev_stat = None 1321- for stat in stats: 1322- if prev_stat: 1323- self.assertTrue(prev_stat.ttot >= stat.ttot) 1324- prev_stat = stat 1325- stats = stats.sort("totaltime", "asc") 1326- prev_stat = None 1327- for stat in stats: 1328- if prev_stat: 1329- self.assertTrue(prev_stat.ttot <= stat.ttot) 1330- prev_stat = stat 1331- stats = stats.sort("schedcount", "desc") 1332- prev_stat = None 1333- for stat in stats: 1334- if prev_stat: 1335- self.assertTrue(prev_stat.sched_count >= stat.sched_count) 1336- prev_stat = stat 1337- stats = stats.sort("name", "desc") 1338- prev_stat = None 1339- for stat in stats: 1340- if prev_stat: 1341- self.assertTrue(prev_stat.name.lower() >= stat.name.lower()) 1342- prev_stat = stat 1343- self.assertRaises( 1344- yappi.YappiError, stats.sort, "invalid_thread_sorttype_arg" 1345- ) 1346- self.assertRaises( 1347- yappi.YappiError, stats.sort, "invalid_thread_sortorder_arg" 1348- ) 1349- 1350- def test_ctx_stats_cpu(self): 1351- 1352- def get_thread_name(): 1353- try: 1354- return threading.current_thread().name 1355- except AttributeError: 1356- return "Anonymous" 1357- 1358- def burn_cpu(sec): 1359- t0 = yappi.get_clock_time() 1360- elapsed = 0 1361- while (elapsed < sec): 1362- for _ in range(1000): 1363- pass 1364- elapsed = yappi.get_clock_time() - t0 1365- 1366- def test(): 1367- 1368- ts = [] 1369- for i in (0.01, 0.05, 0.1): 1370- t = threading.Thread(target=burn_cpu, args=(i, )) 1371- t.name = "burn_cpu-%s" % str(i) 1372- t.start() 1373- ts.append(t) 1374- for t in ts: 1375- t.join() 1376- 1377- yappi.set_clock_type("cpu") 1378- yappi.set_context_name_callback(get_thread_name) 1379- 1380- yappi.start() 1381- 1382- test() 1383- 1384- yappi.stop() 1385- 1386- tstats = yappi.get_thread_stats() 1387- r1 = ''' 1388- burn_cpu-0.1 3 123145356058624 0.100105 8 1389- burn_cpu-0.05 2 123145361313792 0.050149 8 1390- burn_cpu-0.01 1 123145356058624 0.010127 2 1391- MainThread 0 4321620864 0.001632 6 1392- ''' 1393- self.assert_ctx_stats_almost_equal(r1, tstats) 1394- 1395- def test_producer_consumer_with_queues(self): 1396- # we currently just stress yappi, no functionality test is done here. 1397- yappi.start() 1398- if utils.is_py3x(): 1399- from queue import Queue 1400- else: 1401- from Queue import Queue 1402- from threading import Thread 1403- WORKER_THREAD_COUNT = 50 1404- WORK_ITEM_COUNT = 2000 1405- 1406- def worker(): 1407- while True: 1408- item = q.get() 1409- # do the work with item 1410- q.task_done() 1411- 1412- q = Queue() 1413- for i in range(WORKER_THREAD_COUNT): 1414- t = Thread(target=worker) 1415- t.daemon = True 1416- t.start() 1417- 1418- for item in range(WORK_ITEM_COUNT): 1419- q.put(item) 1420- q.join() # block until all tasks are done 1421- #yappi.get_func_stats().sort("callcount").print_all() 1422- yappi.stop() 1423- 1424- def test_temporary_lock_waiting(self): 1425- yappi.start() 1426- _lock = threading.Lock() 1427- 1428- def worker(): 1429- _lock.acquire() 1430- try: 1431- time.sleep(1.0) 1432- finally: 1433- _lock.release() 1434- 1435- t1 = threading.Thread(target=worker) 1436- t2 = threading.Thread(target=worker) 1437- t1.start() 1438- t2.start() 1439- t1.join() 1440- t2.join() 1441- #yappi.get_func_stats().sort("callcount").print_all() 1442- yappi.stop() 1443- 1444- @unittest.skipIf(os.name != "posix", "requires Posix compliant OS") 1445- def test_signals_with_blocking_calls(self): 1446- import signal, os, time 1447- 1448- # just to verify if signal is handled correctly and stats/yappi are not corrupted. 1449- def handler(signum, frame): 1450- raise Exception("Signal handler executed!") 1451- 1452- yappi.start() 1453- signal.signal(signal.SIGALRM, handler) 1454- signal.alarm(1) 1455- self.assertRaises(Exception, time.sleep, 2) 1456- stats = yappi.get_func_stats() 1457- fsh = utils.find_stat_by_name(stats, "handler") 1458- self.assertTrue(fsh is not None) 1459- 1460- @unittest.skipIf(not sys.version_info >= (3, 2), "requires Python 3.2") 1461- def test_concurrent_futures(self): 1462- yappi.start() 1463- from concurrent.futures import ThreadPoolExecutor 1464- with ThreadPoolExecutor(max_workers=5) as executor: 1465- f = executor.submit(pow, 5, 2) 1466- self.assertEqual(f.result(), 25) 1467- time.sleep(1.0) 1468- yappi.stop() 1469- 1470- @unittest.skipIf(not sys.version_info >= (3, 2), "requires Python 3.2") 1471- def test_barrier(self): 1472- yappi.start() 1473- b = threading.Barrier(2, timeout=1) 1474- 1475- def worker(): 1476- try: 1477- b.wait() 1478- except threading.BrokenBarrierError: 1479- pass 1480- except Exception: 1481- raise Exception("BrokenBarrierError not raised") 1482- 1483- t1 = threading.Thread(target=worker) 1484- t1.start() 1485- #b.wait() 1486- t1.join() 1487- yappi.stop() 1488- 1489- 1490-class NonRecursiveFunctions(utils.YappiUnitTestCase): 1491- 1492- def test_abcd(self): 1493- _timings = {"a_1": 6, "b_1": 5, "c_1": 3, "d_1": 1} 1494- _yappi._set_test_timings(_timings) 1495- 1496- def a(): 1497- b() 1498- 1499- def b(): 1500- c() 1501- 1502- def c(): 1503- d() 1504- 1505- def d(): 1506- pass 1507- 1508- stats = utils.run_and_get_func_stats(a) 1509- fsa = utils.find_stat_by_name(stats, 'a') 1510- fsb = utils.find_stat_by_name(stats, 'b') 1511- fsc = utils.find_stat_by_name(stats, 'c') 1512- fsd = utils.find_stat_by_name(stats, 'd') 1513- cfsab = fsa.children[fsb] 1514- cfsbc = fsb.children[fsc] 1515- cfscd = fsc.children[fsd] 1516- 1517- self.assertEqual(fsa.ttot, 6) 1518- self.assertEqual(fsa.tsub, 1) 1519- self.assertEqual(fsb.ttot, 5) 1520- self.assertEqual(fsb.tsub, 2) 1521- self.assertEqual(fsc.ttot, 3) 1522- self.assertEqual(fsc.tsub, 2) 1523- self.assertEqual(fsd.ttot, 1) 1524- self.assertEqual(fsd.tsub, 1) 1525- self.assertEqual(cfsab.ttot, 5) 1526- self.assertEqual(cfsab.tsub, 2) 1527- self.assertEqual(cfsbc.ttot, 3) 1528- self.assertEqual(cfsbc.tsub, 2) 1529- self.assertEqual(cfscd.ttot, 1) 1530- self.assertEqual(cfscd.tsub, 1) 1531- 1532- def test_stop_in_middle(self): 1533- _timings = {"a_1": 6, "b_1": 4} 1534- _yappi._set_test_timings(_timings) 1535- 1536- def a(): 1537- b() 1538- yappi.stop() 1539- 1540- def b(): 1541- time.sleep(0.2) 1542- 1543- yappi.start() 1544- a() 1545- stats = yappi.get_func_stats() 1546- fsa = utils.find_stat_by_name(stats, 'a') 1547- fsb = utils.find_stat_by_name(stats, 'b') 1548- 1549- self.assertEqual(fsa.ncall, 1) 1550- self.assertEqual(fsa.nactualcall, 0) 1551- self.assertEqual(fsa.ttot, 0) # no call_leave called 1552- self.assertEqual(fsa.tsub, 0) # no call_leave called 1553- self.assertEqual(fsb.ttot, 4) 1554- 1555- 1556-class RecursiveFunctions(utils.YappiUnitTestCase): 1557- 1558- def test_fibonacci(self): 1559- 1560- def fib(n): 1561- if n > 1: 1562- return fib(n - 1) + fib(n - 2) 1563- else: 1564- return n 1565- 1566- stats = utils.run_and_get_func_stats(fib, 22) 1567- fs = utils.find_stat_by_name(stats, 'fib') 1568- self.assertEqual(fs.ncall, 57313) 1569- self.assertEqual(fs.ttot, fs.tsub) 1570- 1571- def test_abcadc(self): 1572- _timings = { 1573- "a_1": 20, 1574- "b_1": 19, 1575- "c_1": 17, 1576- "a_2": 13, 1577- "d_1": 12, 1578- "c_2": 10, 1579- "a_3": 5 1580- } 1581- _yappi._set_test_timings(_timings) 1582- 1583- def a(n): 1584- if n == 3: 1585- return 1586- if n == 1 + 1: 1587- d(n) 1588- else: 1589- b(n) 1590- 1591- def b(n): 1592- c(n) 1593- 1594- def c(n): 1595- a(n + 1) 1596- 1597- def d(n): 1598- c(n) 1599- 1600- stats = utils.run_and_get_func_stats(a, 1) 1601- fsa = utils.find_stat_by_name(stats, 'a') 1602- fsb = utils.find_stat_by_name(stats, 'b') 1603- fsc = utils.find_stat_by_name(stats, 'c') 1604- fsd = utils.find_stat_by_name(stats, 'd') 1605- self.assertEqual(fsa.ncall, 3) 1606- self.assertEqual(fsa.nactualcall, 1) 1607- self.assertEqual(fsa.ttot, 20) 1608- self.assertEqual(fsa.tsub, 7) 1609- self.assertEqual(fsb.ttot, 19) 1610- self.assertEqual(fsb.tsub, 2) 1611- self.assertEqual(fsc.ttot, 17) 1612- self.assertEqual(fsc.tsub, 9) 1613- self.assertEqual(fsd.ttot, 12) 1614- self.assertEqual(fsd.tsub, 2) 1615- cfsca = fsc.children[fsa] 1616- self.assertEqual(cfsca.nactualcall, 0) 1617- self.assertEqual(cfsca.ncall, 2) 1618- self.assertEqual(cfsca.ttot, 13) 1619- self.assertEqual(cfsca.tsub, 6) 1620- 1621- def test_aaaa(self): 1622- _timings = {"d_1": 9, "d_2": 7, "d_3": 3, "d_4": 2} 1623- _yappi._set_test_timings(_timings) 1624- 1625- def d(n): 1626- if n == 3: 1627- return 1628- d(n + 1) 1629- 1630- stats = utils.run_and_get_func_stats(d, 0) 1631- fsd = utils.find_stat_by_name(stats, 'd') 1632- self.assertEqual(fsd.ncall, 4) 1633- self.assertEqual(fsd.nactualcall, 1) 1634- self.assertEqual(fsd.ttot, 9) 1635- self.assertEqual(fsd.tsub, 9) 1636- cfsdd = fsd.children[fsd] 1637- self.assertEqual(cfsdd.ttot, 7) 1638- self.assertEqual(cfsdd.tsub, 7) 1639- self.assertEqual(cfsdd.ncall, 3) 1640- self.assertEqual(cfsdd.nactualcall, 0) 1641- 1642- def test_abcabc(self): 1643- _timings = { 1644- "a_1": 20, 1645- "b_1": 19, 1646- "c_1": 17, 1647- "a_2": 13, 1648- "b_2": 11, 1649- "c_2": 9, 1650- "a_3": 6 1651- } 1652- _yappi._set_test_timings(_timings) 1653- 1654- def a(n): 1655- if n == 3: 1656- return 1657- else: 1658- b(n) 1659- 1660- def b(n): 1661- c(n) 1662- 1663- def c(n): 1664- a(n + 1) 1665- 1666- stats = utils.run_and_get_func_stats(a, 1) 1667- fsa = utils.find_stat_by_name(stats, 'a') 1668- fsb = utils.find_stat_by_name(stats, 'b') 1669- fsc = utils.find_stat_by_name(stats, 'c') 1670- self.assertEqual(fsa.ncall, 3) 1671- self.assertEqual(fsa.nactualcall, 1) 1672- self.assertEqual(fsa.ttot, 20) 1673- self.assertEqual(fsa.tsub, 9) 1674- self.assertEqual(fsb.ttot, 19) 1675- self.assertEqual(fsb.tsub, 4) 1676- self.assertEqual(fsc.ttot, 17) 1677- self.assertEqual(fsc.tsub, 7) 1678- cfsab = fsa.children[fsb] 1679- cfsbc = fsb.children[fsc] 1680- cfsca = fsc.children[fsa] 1681- self.assertEqual(cfsab.ttot, 19) 1682- self.assertEqual(cfsab.tsub, 4) 1683- self.assertEqual(cfsbc.ttot, 17) 1684- self.assertEqual(cfsbc.tsub, 7) 1685- self.assertEqual(cfsca.ttot, 13) 1686- self.assertEqual(cfsca.tsub, 8) 1687- 1688- def test_abcbca(self): 1689- _timings = {"a_1": 10, "b_1": 9, "c_1": 7, "b_2": 4, "c_2": 2, "a_2": 1} 1690- _yappi._set_test_timings(_timings) 1691- self._ncall = 1 1692- 1693- def a(): 1694- if self._ncall == 1: 1695- b() 1696- else: 1697- return 1698- 1699- def b(): 1700- c() 1701- 1702- def c(): 1703- if self._ncall == 1: 1704- self._ncall += 1 1705- b() 1706- else: 1707- a() 1708- 1709- stats = utils.run_and_get_func_stats(a) 1710- fsa = utils.find_stat_by_name(stats, 'a') 1711- fsb = utils.find_stat_by_name(stats, 'b') 1712- fsc = utils.find_stat_by_name(stats, 'c') 1713- cfsab = fsa.children[fsb] 1714- cfsbc = fsb.children[fsc] 1715- cfsca = fsc.children[fsa] 1716- self.assertEqual(fsa.ttot, 10) 1717- self.assertEqual(fsa.tsub, 2) 1718- self.assertEqual(fsb.ttot, 9) 1719- self.assertEqual(fsb.tsub, 4) 1720- self.assertEqual(fsc.ttot, 7) 1721- self.assertEqual(fsc.tsub, 4) 1722- self.assertEqual(cfsab.ttot, 9) 1723- self.assertEqual(cfsab.tsub, 2) 1724- self.assertEqual(cfsbc.ttot, 7) 1725- self.assertEqual(cfsbc.tsub, 4) 1726- self.assertEqual(cfsca.ttot, 1) 1727- self.assertEqual(cfsca.tsub, 1) 1728- self.assertEqual(cfsca.ncall, 1) 1729- self.assertEqual(cfsca.nactualcall, 0) 1730- 1731- def test_aabccb(self): 1732- _timings = { 1733- "a_1": 13, 1734- "a_2": 11, 1735- "b_1": 9, 1736- "c_1": 5, 1737- "c_2": 3, 1738- "b_2": 1 1739- } 1740- _yappi._set_test_timings(_timings) 1741- self._ncall = 1 1742- 1743- def a(): 1744- if self._ncall == 1: 1745- self._ncall += 1 1746- a() 1747- else: 1748- b() 1749- 1750- def b(): 1751- if self._ncall == 3: 1752- return 1753- else: 1754- c() 1755- 1756- def c(): 1757- if self._ncall == 2: 1758- self._ncall += 1 1759- c() 1760- else: 1761- b() 1762- 1763- stats = utils.run_and_get_func_stats(a) 1764- fsa = utils.find_stat_by_name(stats, 'a') 1765- fsb = utils.find_stat_by_name(stats, 'b') 1766- fsc = utils.find_stat_by_name(stats, 'c') 1767- cfsaa = fsa.children[fsa.index] 1768- cfsab = fsa.children[fsb] 1769- cfsbc = fsb.children[fsc.full_name] 1770- cfscc = fsc.children[fsc] 1771- cfscb = fsc.children[fsb] 1772- self.assertEqual(fsb.ttot, 9) 1773- self.assertEqual(fsb.tsub, 5) 1774- self.assertEqual(cfsbc.ttot, 5) 1775- self.assertEqual(cfsbc.tsub, 2) 1776- self.assertEqual(fsa.ttot, 13) 1777- self.assertEqual(fsa.tsub, 4) 1778- self.assertEqual(cfsab.ttot, 9) 1779- self.assertEqual(cfsab.tsub, 4) 1780- self.assertEqual(cfsaa.ttot, 11) 1781- self.assertEqual(cfsaa.tsub, 2) 1782- self.assertEqual(fsc.ttot, 5) 1783- self.assertEqual(fsc.tsub, 4) 1784- 1785- def test_abaa(self): 1786- _timings = {"a_1": 13, "b_1": 10, "a_2": 9, "a_3": 5} 1787- _yappi._set_test_timings(_timings) 1788- 1789- self._ncall = 1 1790- 1791- def a(): 1792- if self._ncall == 1: 1793- b() 1794- elif self._ncall == 2: 1795- self._ncall += 1 1796- a() 1797- else: 1798- return 1799- 1800- def b(): 1801- self._ncall += 1 1802- a() 1803- 1804- stats = utils.run_and_get_func_stats(a) 1805- fsa = utils.find_stat_by_name(stats, 'a') 1806- fsb = utils.find_stat_by_name(stats, 'b') 1807- cfsaa = fsa.children[fsa] 1808- cfsba = fsb.children[fsa] 1809- self.assertEqual(fsb.ttot, 10) 1810- self.assertEqual(fsb.tsub, 1) 1811- self.assertEqual(fsa.ttot, 13) 1812- self.assertEqual(fsa.tsub, 12) 1813- self.assertEqual(cfsaa.ttot, 5) 1814- self.assertEqual(cfsaa.tsub, 5) 1815- self.assertEqual(cfsba.ttot, 9) 1816- self.assertEqual(cfsba.tsub, 4) 1817- 1818- def test_aabb(self): 1819- _timings = {"a_1": 13, "a_2": 10, "b_1": 9, "b_2": 5} 1820- _yappi._set_test_timings(_timings) 1821- 1822- self._ncall = 1 1823- 1824- def a(): 1825- if self._ncall == 1: 1826- self._ncall += 1 1827- a() 1828- elif self._ncall == 2: 1829- b() 1830- else: 1831- return 1832- 1833- def b(): 1834- if self._ncall == 2: 1835- self._ncall += 1 1836- b() 1837- else: 1838- return 1839- 1840- stats = utils.run_and_get_func_stats(a) 1841- fsa = utils.find_stat_by_name(stats, 'a') 1842- fsb = utils.find_stat_by_name(stats, 'b') 1843- cfsaa = fsa.children[fsa] 1844- cfsab = fsa.children[fsb] 1845- cfsbb = fsb.children[fsb] 1846- self.assertEqual(fsa.ttot, 13) 1847- self.assertEqual(fsa.tsub, 4) 1848- self.assertEqual(fsb.ttot, 9) 1849- self.assertEqual(fsb.tsub, 9) 1850- self.assertEqual(cfsaa.ttot, 10) 1851- self.assertEqual(cfsaa.tsub, 1) 1852- self.assertEqual(cfsab.ttot, 9) 1853- self.assertEqual(cfsab.tsub, 4) 1854- self.assertEqual(cfsbb.ttot, 5) 1855- self.assertEqual(cfsbb.tsub, 5) 1856- 1857- def test_abbb(self): 1858- _timings = {"a_1": 13, "b_1": 10, "b_2": 6, "b_3": 1} 1859- _yappi._set_test_timings(_timings) 1860- 1861- self._ncall = 1 1862- 1863- def a(): 1864- if self._ncall == 1: 1865- b() 1866- 1867- def b(): 1868- if self._ncall == 3: 1869- return 1870- self._ncall += 1 1871- b() 1872- 1873- stats = utils.run_and_get_func_stats(a) 1874- fsa = utils.find_stat_by_name(stats, 'a') 1875- fsb = utils.find_stat_by_name(stats, 'b') 1876- cfsab = fsa.children[fsb] 1877- cfsbb = fsb.children[fsb] 1878- self.assertEqual(fsa.ttot, 13) 1879- self.assertEqual(fsa.tsub, 3) 1880- self.assertEqual(fsb.ttot, 10) 1881- self.assertEqual(fsb.tsub, 10) 1882- self.assertEqual(fsb.ncall, 3) 1883- self.assertEqual(fsb.nactualcall, 1) 1884- self.assertEqual(cfsab.ttot, 10) 1885- self.assertEqual(cfsab.tsub, 4) 1886- self.assertEqual(cfsbb.ttot, 6) 1887- self.assertEqual(cfsbb.tsub, 6) 1888- self.assertEqual(cfsbb.nactualcall, 0) 1889- self.assertEqual(cfsbb.ncall, 2) 1890- 1891- def test_aaab(self): 1892- _timings = {"a_1": 13, "a_2": 10, "a_3": 6, "b_1": 1} 1893- _yappi._set_test_timings(_timings) 1894- 1895- self._ncall = 1 1896- 1897- def a(): 1898- if self._ncall == 3: 1899- b() 1900- return 1901- self._ncall += 1 1902- a() 1903- 1904- def b(): 1905- return 1906- 1907- stats = utils.run_and_get_func_stats(a) 1908- fsa = utils.find_stat_by_name(stats, 'a') 1909- fsb = utils.find_stat_by_name(stats, 'b') 1910- cfsaa = fsa.children[fsa] 1911- cfsab = fsa.children[fsb] 1912- self.assertEqual(fsa.ttot, 13) 1913- self.assertEqual(fsa.tsub, 12) 1914- self.assertEqual(fsb.ttot, 1) 1915- self.assertEqual(fsb.tsub, 1) 1916- self.assertEqual(cfsaa.ttot, 10) 1917- self.assertEqual(cfsaa.tsub, 9) 1918- self.assertEqual(cfsab.ttot, 1) 1919- self.assertEqual(cfsab.tsub, 1) 1920- 1921- def test_abab(self): 1922- _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1} 1923- _yappi._set_test_timings(_timings) 1924- 1925- self._ncall = 1 1926- 1927- def a(): 1928- b() 1929- 1930- def b(): 1931- if self._ncall == 2: 1932- return 1933- self._ncall += 1 1934- a() 1935- 1936- stats = utils.run_and_get_func_stats(a) 1937- fsa = utils.find_stat_by_name(stats, 'a') 1938- fsb = utils.find_stat_by_name(stats, 'b') 1939- cfsab = fsa.children[fsb] 1940- cfsba = fsb.children[fsa] 1941- self.assertEqual(fsa.ttot, 13) 1942- self.assertEqual(fsa.tsub, 8) 1943- self.assertEqual(fsb.ttot, 10) 1944- self.assertEqual(fsb.tsub, 5) 1945- self.assertEqual(cfsab.ttot, 10) 1946- self.assertEqual(cfsab.tsub, 5) 1947- self.assertEqual(cfsab.ncall, 2) 1948- self.assertEqual(cfsab.nactualcall, 1) 1949- self.assertEqual(cfsba.ttot, 6) 1950- self.assertEqual(cfsba.tsub, 5) 1951- 1952- 1953-if __name__ == '__main__': 1954- # import sys;sys.argv = ['', 'BasicUsage.test_run_as_script'] 1955- # import sys;sys.argv = ['', 'MultithreadedScenarios.test_subsequent_profile'] 1956- unittest.main() 1957+import os 1958+import sys 1959+import time 1960+import threading 1961+import unittest 1962+import yappi 1963+import _yappi 1964+import tests.utils as utils 1965+import multiprocessing # added to fix http://bugs.python.org/issue15881 for > Py2.6 1966+import subprocess 1967+ 1968+_counter = 0 1969+ 1970+ 1971+class BasicUsage(utils.YappiUnitTestCase): 1972+ 1973+ def test_callback_function_int_return_overflow(self): 1974+ # this test is just here to check if any errors are generated, as the err 1975+ # is printed in C side, I did not include it here. THere are ways to test 1976+ # this deterministically, I did not bother 1977+ import ctypes 1978+ 1979+ def _unsigned_overflow_margin(): 1980+ return 2**(ctypes.sizeof(ctypes.c_void_p) * 8) - 1 1981+ 1982+ def foo(): 1983+ pass 1984+ 1985+ #with utils.captured_output() as (out, err): 1986+ yappi.set_context_id_callback(_unsigned_overflow_margin) 1987+ yappi.set_tag_callback(_unsigned_overflow_margin) 1988+ yappi.start() 1989+ foo() 1990+ 1991+ def test_issue60(self): 1992+ 1993+ def foo(): 1994+ buf = bytearray() 1995+ buf += b't' * 200 1996+ view = memoryview(buf)[10:] 1997+ view = view.tobytes() 1998+ del buf[:10] # this throws exception 1999+ return view 2000+ 2001+ yappi.start(builtins=True) 2002+ foo() 2003+ self.assertTrue( 2004+ len( 2005+ yappi.get_func_stats( 2006+ filter_callback=lambda x: yappi. 2007+ func_matches(x, [memoryview.tobytes]) 2008+ ) 2009+ ) > 0 2010+ ) 2011+ yappi.stop() 2012+ 2013+ def test_issue54(self): 2014+ 2015+ def _tag_cbk(): 2016+ global _counter 2017+ _counter += 1 2018+ return _counter 2019+ 2020+ def a(): 2021+ pass 2022+ 2023+ def b(): 2024+ pass 2025+ 2026+ yappi.set_tag_callback(_tag_cbk) 2027+ yappi.start() 2028+ a() 2029+ a() 2030+ a() 2031+ yappi.stop() 2032+ stats = yappi.get_func_stats() 2033+ self.assertEqual(stats.pop().ncall, 3) # aggregated if no tag is given 2034+ stats = yappi.get_func_stats(tag=1) 2035+ 2036+ for i in range(1, 3): 2037+ stats = yappi.get_func_stats(tag=i) 2038+ stats = yappi.get_func_stats( 2039+ tag=i, filter_callback=lambda x: yappi.func_matches(x, [a]) 2040+ ) 2041+ 2042+ stat = stats.pop() 2043+ self.assertEqual(stat.ncall, 1) 2044+ 2045+ yappi.set_tag_callback(None) 2046+ yappi.clear_stats() 2047+ yappi.start() 2048+ b() 2049+ b() 2050+ stats = yappi.get_func_stats() 2051+ self.assertEqual(len(stats), 1) 2052+ stat = stats.pop() 2053+ self.assertEqual(stat.ncall, 2) 2054+ 2055+ def test_filter(self): 2056+ 2057+ def a(): 2058+ pass 2059+ 2060+ def b(): 2061+ a() 2062+ 2063+ def c(): 2064+ b() 2065+ 2066+ _TCOUNT = 5 2067+ 2068+ ts = [] 2069+ yappi.start() 2070+ for i in range(_TCOUNT): 2071+ t = threading.Thread(target=c) 2072+ t.start() 2073+ ts.append(t) 2074+ 2075+ for t in ts: 2076+ t.join() 2077+ 2078+ yappi.stop() 2079+ 2080+ ctx_ids = [] 2081+ for tstat in yappi.get_thread_stats(): 2082+ if tstat.name == '_MainThread': 2083+ main_ctx_id = tstat.id 2084+ else: 2085+ ctx_ids.append(tstat.id) 2086+ 2087+ fstats = yappi.get_func_stats(filter={"ctx_id": 9}) 2088+ self.assertTrue(fstats.empty()) 2089+ fstats = yappi.get_func_stats( 2090+ filter={ 2091+ "ctx_id": main_ctx_id, 2092+ "name": "c" 2093+ } 2094+ ) # main thread 2095+ self.assertTrue(fstats.empty()) 2096+ 2097+ for i in ctx_ids: 2098+ fstats = yappi.get_func_stats( 2099+ filter={ 2100+ "ctx_id": i, 2101+ "name": "a", 2102+ "ncall": 1 2103+ } 2104+ ) 2105+ self.assertEqual(fstats.pop().ncall, 1) 2106+ fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "b"}) 2107+ self.assertEqual(fstats.pop().ncall, 1) 2108+ fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "c"}) 2109+ self.assertEqual(fstats.pop().ncall, 1) 2110+ 2111+ yappi.clear_stats() 2112+ yappi.start(builtins=True) 2113+ time.sleep(0.1) 2114+ yappi.stop() 2115+ fstats = yappi.get_func_stats(filter={"module": "time"}) 2116+ self.assertEqual(len(fstats), 1) 2117+ 2118+ # invalid filters` 2119+ self.assertRaises( 2120+ Exception, yappi.get_func_stats, filter={'tag': "sss"} 2121+ ) 2122+ self.assertRaises( 2123+ Exception, yappi.get_func_stats, filter={'ctx_id': "None"} 2124+ ) 2125+ 2126+ def test_filter_callback(self): 2127+ 2128+ def a(): 2129+ time.sleep(0.1) 2130+ 2131+ def b(): 2132+ a() 2133+ 2134+ def c(): 2135+ pass 2136+ 2137+ def d(): 2138+ pass 2139+ 2140+ yappi.set_clock_type("wall") 2141+ yappi.start(builtins=True) 2142+ a() 2143+ b() 2144+ c() 2145+ d() 2146+ stats = yappi.get_func_stats( 2147+ filter_callback=lambda x: yappi.func_matches(x, [a, b]) 2148+ ) 2149+ #stats.print_all() 2150+ r1 = ''' 2151+ tests/test_functionality.py:98 a 2 0.000000 0.200350 0.100175 2152+ tests/test_functionality.py:101 b 1 0.000000 0.120000 0.100197 2153+ ''' 2154+ self.assert_traces_almost_equal(r1, stats) 2155+ self.assertEqual(len(stats), 2) 2156+ stats = yappi.get_func_stats( 2157+ filter_callback=lambda x: yappi. 2158+ module_matches(x, [sys.modules[__name__]]) 2159+ ) 2160+ r1 = ''' 2161+ tests/test_functionality.py:98 a 2 0.000000 0.230130 0.115065 2162+ tests/test_functionality.py:101 b 1 0.000000 0.120000 0.109011 2163+ tests/test_functionality.py:104 c 1 0.000000 0.000002 0.000002 2164+ tests/test_functionality.py:107 d 1 0.000000 0.000001 0.000001 2165+ ''' 2166+ self.assert_traces_almost_equal(r1, stats) 2167+ self.assertEqual(len(stats), 4) 2168+ 2169+ stats = yappi.get_func_stats( 2170+ filter_callback=lambda x: yappi.func_matches(x, [time.sleep]) 2171+ ) 2172+ self.assertEqual(len(stats), 1) 2173+ r1 = ''' 2174+ time.sleep 2 0.206804 0.220000 0.103402 2175+ ''' 2176+ self.assert_traces_almost_equal(r1, stats) 2177+ 2178+ def test_print_formatting(self): 2179+ 2180+ def a(): 2181+ pass 2182+ 2183+ def b(): 2184+ a() 2185+ 2186+ func_cols = { 2187+ 1: ("name", 48), 2188+ 0: ("ncall", 5), 2189+ 2: ("tsub", 8), 2190+ } 2191+ thread_cols = { 2192+ 1: ("name", 48), 2193+ 0: ("ttot", 8), 2194+ } 2195+ 2196+ yappi.start() 2197+ a() 2198+ b() 2199+ yappi.stop() 2200+ fs = yappi.get_func_stats() 2201+ cs = fs[1].children 2202+ ts = yappi.get_thread_stats() 2203+ #fs.print_all(out=sys.stderr, columns={1:("name", 70), }) 2204+ #cs.print_all(out=sys.stderr, columns=func_cols) 2205+ #ts.print_all(out=sys.stderr, columns=thread_cols) 2206+ #cs.print_all(out=sys.stderr, columns={}) 2207+ 2208+ self.assertRaises( 2209+ yappi.YappiError, fs.print_all, columns={1: ("namee", 9)} 2210+ ) 2211+ self.assertRaises( 2212+ yappi.YappiError, cs.print_all, columns={1: ("dd", 0)} 2213+ ) 2214+ self.assertRaises( 2215+ yappi.YappiError, ts.print_all, columns={1: ("tidd", 0)} 2216+ ) 2217+ 2218+ def test_get_clock(self): 2219+ yappi.set_clock_type('cpu') 2220+ self.assertEqual('cpu', yappi.get_clock_type()) 2221+ clock_info = yappi.get_clock_info() 2222+ self.assertTrue('api' in clock_info) 2223+ self.assertTrue('resolution' in clock_info) 2224+ 2225+ yappi.set_clock_type('wall') 2226+ self.assertEqual('wall', yappi.get_clock_type()) 2227+ 2228+ t0 = yappi.get_clock_time() 2229+ time.sleep(0.1) 2230+ duration = yappi.get_clock_time() - t0 2231+ self.assertTrue(0.05 < duration < 0.3) 2232+ 2233+ def test_profile_decorator(self): 2234+ 2235+ def aggregate(func, stats): 2236+ fname = "tests/%s.profile" % (func.__name__) 2237+ try: 2238+ stats.add(fname) 2239+ except IOError: 2240+ pass 2241+ stats.save(fname) 2242+ raise Exception("messing around") 2243+ 2244+ @yappi.profile(return_callback=aggregate) 2245+ def a(x, y): 2246+ if x + y == 25: 2247+ raise Exception("") 2248+ return x + y 2249+ 2250+ def b(): 2251+ pass 2252+ 2253+ try: 2254+ os.remove( 2255+ "tests/a.profile" 2256+ ) # remove the one from prev test, if available 2257+ except: 2258+ pass 2259+ 2260+ # global profile is on to mess things up 2261+ yappi.start() 2262+ b() 2263+ 2264+ # assert functionality and call function at same time 2265+ try: 2266+ self.assertEqual(a(1, 2), 3) 2267+ except: 2268+ pass 2269+ try: 2270+ self.assertEqual(a(2, 5), 7) 2271+ except: 2272+ pass 2273+ try: 2274+ a(4, 21) 2275+ except: 2276+ pass 2277+ stats = yappi.get_func_stats().add("tests/a.profile") 2278+ fsa = utils.find_stat_by_name(stats, 'a') 2279+ self.assertEqual(fsa.ncall, 3) 2280+ self.assertEqual(len(stats), 1) # b() should be cleared out. 2281+ 2282+ @yappi.profile(return_callback=aggregate) 2283+ def count_down_rec(n): 2284+ if n == 0: 2285+ return 2286+ count_down_rec(n - 1) 2287+ 2288+ try: 2289+ os.remove( 2290+ "tests/count_down_rec.profile" 2291+ ) # remove the one from prev test, if available 2292+ except: 2293+ pass 2294+ 2295+ try: 2296+ count_down_rec(4) 2297+ except: 2298+ pass 2299+ try: 2300+ count_down_rec(3) 2301+ except: 2302+ pass 2303+ 2304+ stats = yappi.YFuncStats("tests/count_down_rec.profile") 2305+ fsrec = utils.find_stat_by_name(stats, 'count_down_rec') 2306+ self.assertEqual(fsrec.ncall, 9) 2307+ self.assertEqual(fsrec.nactualcall, 2) 2308+ 2309+ def test_strip_dirs(self): 2310+ 2311+ def a(): 2312+ pass 2313+ 2314+ stats = utils.run_and_get_func_stats(a, ) 2315+ stats.strip_dirs() 2316+ fsa = utils.find_stat_by_name(stats, "a") 2317+ self.assertEqual(fsa.module, os.path.basename(fsa.module)) 2318+ 2319+ @unittest.skipIf(os.name == "nt", "do not run on Windows") 2320+ def test_run_as_script(self): 2321+ import re 2322+ p = subprocess.Popen( 2323+ ['yappi', os.path.join('./tests', 'run_as_script.py')], 2324+ stdout=subprocess.PIPE 2325+ ) 2326+ out, err = p.communicate() 2327+ self.assertEqual(p.returncode, 0) 2328+ func_stats, thread_stats = re.split( 2329+ b'name\\s+id\\s+tid\\s+ttot\\s+scnt\\s*\n', out 2330+ ) 2331+ self.assertTrue(b'FancyThread' in thread_stats) 2332+ 2333+ def test_yappi_overhead(self): 2334+ LOOP_COUNT = 100000 2335+ 2336+ def a(): 2337+ pass 2338+ 2339+ def b(): 2340+ for i in range(LOOP_COUNT): 2341+ a() 2342+ 2343+ t0 = time.time() 2344+ yappi.start() 2345+ b() 2346+ yappi.stop() 2347+ time_with_yappi = time.time() - t0 2348+ t0 = time.time() 2349+ b() 2350+ time_without_yappi = time.time() - t0 2351+ if time_without_yappi == 0: 2352+ time_without_yappi = 0.000001 2353+ 2354+ # in latest v0.82, I calculated this as close to "7.0" in my machine. 2355+ # however, %83 of this overhead is coming from tickcount(). The other %17 2356+ # seems to have been evenly distributed to the internal bookkeeping 2357+ # structures/algorithms which seems acceptable. Note that our test only 2358+ # tests one function being profiled at-a-time in a short interval. 2359+ # profiling high number of functions in a small time 2360+ # is a different beast, (which is pretty unlikely in most applications) 2361+ # So as a conclusion: I cannot see any optimization window for Yappi that 2362+ # is worth implementing as we will only optimize %17 of the time. 2363+ sys.stderr.write("\r\nYappi puts %0.1f times overhead to the profiled application in average.\r\n" % \ 2364+ (time_with_yappi / time_without_yappi)) 2365+ 2366+ def test_clear_stats_while_running(self): 2367+ 2368+ def a(): 2369+ pass 2370+ 2371+ yappi.start() 2372+ a() 2373+ yappi.clear_stats() 2374+ a() 2375+ stats = yappi.get_func_stats() 2376+ fsa = utils.find_stat_by_name(stats, 'a') 2377+ self.assertEqual(fsa.ncall, 1) 2378+ 2379+ def test_generator(self): 2380+ 2381+ def _gen(n): 2382+ while (n > 0): 2383+ yield n 2384+ n -= 1 2385+ 2386+ yappi.start() 2387+ for x in _gen(5): 2388+ pass 2389+ self.assertTrue( 2390+ yappi.convert2pstats(yappi.get_func_stats()) is not None 2391+ ) 2392+ 2393+ def test_slice_child_stats_and_strip_dirs(self): 2394+ 2395+ def b(): 2396+ for i in range(10000000): 2397+ pass 2398+ 2399+ def a(): 2400+ b() 2401+ 2402+ yappi.start(builtins=True) 2403+ a() 2404+ stats = yappi.get_func_stats() 2405+ fsa = utils.find_stat_by_name(stats, 'a') 2406+ fsb = utils.find_stat_by_name(stats, 'b') 2407+ self.assertTrue(fsa.children[0:1] is not None) 2408+ prev_afullname = fsa.full_name 2409+ prev_bchildfullname = fsa.children[fsb].full_name 2410+ stats.strip_dirs() 2411+ self.assertTrue(len(prev_afullname) > len(fsa.full_name)) 2412+ self.assertTrue( 2413+ len(prev_bchildfullname) > len(fsa.children[fsb].full_name) 2414+ ) 2415+ 2416+ def test_children_stat_functions(self): 2417+ _timings = {"a_1": 5, "b_1": 3, "c_1": 1} 2418+ _yappi._set_test_timings(_timings) 2419+ 2420+ def b(): 2421+ pass 2422+ 2423+ def c(): 2424+ pass 2425+ 2426+ def a(): 2427+ b() 2428+ c() 2429+ 2430+ yappi.start() 2431+ a() 2432+ b() # non-child call 2433+ c() # non-child call 2434+ stats = yappi.get_func_stats() 2435+ fsa = utils.find_stat_by_name(stats, 'a') 2436+ childs_of_a = fsa.children.get().sort("tavg", "desc") 2437+ prev_item = None 2438+ for item in childs_of_a: 2439+ if prev_item: 2440+ self.assertTrue(prev_item.tavg > item.tavg) 2441+ prev_item = item 2442+ childs_of_a.sort("name", "desc") 2443+ prev_item = None 2444+ for item in childs_of_a: 2445+ if prev_item: 2446+ self.assertTrue(prev_item.name > item.name) 2447+ prev_item = item 2448+ childs_of_a.clear() 2449+ self.assertTrue(childs_of_a.empty()) 2450+ 2451+ def test_no_stats_different_clock_type_load(self): 2452+ 2453+ def a(): 2454+ pass 2455+ 2456+ yappi.start() 2457+ a() 2458+ yappi.stop() 2459+ yappi.get_func_stats().save("tests/ystats1.ys") 2460+ yappi.clear_stats() 2461+ yappi.set_clock_type("WALL") 2462+ yappi.start() 2463+ yappi.stop() 2464+ stats = yappi.get_func_stats().add("tests/ystats1.ys") 2465+ fsa = utils.find_stat_by_name(stats, 'a') 2466+ self.assertTrue(fsa is not None) 2467+ 2468+ def test_subsequent_profile(self): 2469+ _timings = {"a_1": 1, "b_1": 1} 2470+ _yappi._set_test_timings(_timings) 2471+ 2472+ def a(): 2473+ pass 2474+ 2475+ def b(): 2476+ pass 2477+ 2478+ yappi.start() 2479+ a() 2480+ yappi.stop() 2481+ yappi.start() 2482+ b() 2483+ yappi.stop() 2484+ stats = yappi.get_func_stats() 2485+ fsa = utils.find_stat_by_name(stats, 'a') 2486+ fsb = utils.find_stat_by_name(stats, 'b') 2487+ self.assertTrue(fsa is not None) 2488+ self.assertTrue(fsb is not None) 2489+ self.assertEqual(fsa.ttot, 1) 2490+ self.assertEqual(fsb.ttot, 1) 2491+ 2492+ def test_lambda(self): 2493+ f = lambda: time.sleep(0.3) 2494+ yappi.set_clock_type("wall") 2495+ yappi.start() 2496+ f() 2497+ stats = yappi.get_func_stats() 2498+ fsa = utils.find_stat_by_name(stats, '<lambda>') 2499+ self.assertTrue(fsa.ttot > 0.1) 2500+ 2501+ def test_module_stress(self): 2502+ self.assertEqual(yappi.is_running(), False) 2503+ 2504+ yappi.start() 2505+ yappi.clear_stats() 2506+ self.assertRaises(_yappi.error, yappi.set_clock_type, "wall") 2507+ 2508+ yappi.stop() 2509+ yappi.clear_stats() 2510+ yappi.set_clock_type("cpu") 2511+ self.assertRaises(yappi.YappiError, yappi.set_clock_type, "dummy") 2512+ self.assertEqual(yappi.is_running(), False) 2513+ yappi.clear_stats() 2514+ yappi.clear_stats() 2515+ 2516+ def test_stat_sorting(self): 2517+ _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1} 2518+ _yappi._set_test_timings(_timings) 2519+ 2520+ self._ncall = 1 2521+ 2522+ def a(): 2523+ b() 2524+ 2525+ def b(): 2526+ if self._ncall == 2: 2527+ return 2528+ self._ncall += 1 2529+ a() 2530+ 2531+ stats = utils.run_and_get_func_stats(a) 2532+ stats = stats.sort("totaltime", "desc") 2533+ prev_stat = None 2534+ for stat in stats: 2535+ if prev_stat: 2536+ self.assertTrue(prev_stat.ttot >= stat.ttot) 2537+ prev_stat = stat 2538+ stats = stats.sort("totaltime", "asc") 2539+ prev_stat = None 2540+ for stat in stats: 2541+ if prev_stat: 2542+ self.assertTrue(prev_stat.ttot <= stat.ttot) 2543+ prev_stat = stat 2544+ stats = stats.sort("avgtime", "asc") 2545+ prev_stat = None 2546+ for stat in stats: 2547+ if prev_stat: 2548+ self.assertTrue(prev_stat.tavg <= stat.tavg) 2549+ prev_stat = stat 2550+ stats = stats.sort("name", "asc") 2551+ prev_stat = None 2552+ for stat in stats: 2553+ if prev_stat: 2554+ self.assertTrue(prev_stat.name <= stat.name) 2555+ prev_stat = stat 2556+ stats = stats.sort("subtime", "asc") 2557+ prev_stat = None 2558+ for stat in stats: 2559+ if prev_stat: 2560+ self.assertTrue(prev_stat.tsub <= stat.tsub) 2561+ prev_stat = stat 2562+ 2563+ self.assertRaises( 2564+ yappi.YappiError, stats.sort, "invalid_func_sorttype_arg" 2565+ ) 2566+ self.assertRaises( 2567+ yappi.YappiError, stats.sort, "totaltime", 2568+ "invalid_func_sortorder_arg" 2569+ ) 2570+ 2571+ def test_start_flags(self): 2572+ self.assertEqual(_yappi._get_start_flags(), None) 2573+ yappi.start() 2574+ 2575+ def a(): 2576+ pass 2577+ 2578+ a() 2579+ self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0) 2580+ self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1) 2581+ self.assertEqual(len(yappi.get_thread_stats()), 1) 2582+ 2583+ def test_builtin_profiling(self): 2584+ 2585+ def a(): 2586+ time.sleep(0.4) # is a builtin function 2587+ 2588+ yappi.set_clock_type('wall') 2589+ 2590+ yappi.start(builtins=True) 2591+ a() 2592+ stats = yappi.get_func_stats() 2593+ fsa = utils.find_stat_by_name(stats, 'sleep') 2594+ self.assertTrue(fsa is not None) 2595+ self.assertTrue(fsa.ttot > 0.3) 2596+ yappi.stop() 2597+ yappi.clear_stats() 2598+ 2599+ def a(): 2600+ pass 2601+ 2602+ yappi.start() 2603+ t = threading.Thread(target=a) 2604+ t.start() 2605+ t.join() 2606+ stats = yappi.get_func_stats() 2607+ 2608+ def test_singlethread_profiling(self): 2609+ yappi.set_clock_type('wall') 2610+ 2611+ def a(): 2612+ time.sleep(0.2) 2613+ 2614+ class Worker1(threading.Thread): 2615+ 2616+ def a(self): 2617+ time.sleep(0.3) 2618+ 2619+ def run(self): 2620+ self.a() 2621+ 2622+ yappi.start(profile_threads=False) 2623+ 2624+ c = Worker1() 2625+ c.start() 2626+ c.join() 2627+ a() 2628+ stats = yappi.get_func_stats() 2629+ fsa1 = utils.find_stat_by_name(stats, 'Worker1.a') 2630+ fsa2 = utils.find_stat_by_name(stats, 'a') 2631+ self.assertTrue(fsa1 is None) 2632+ self.assertTrue(fsa2 is not None) 2633+ self.assertTrue(fsa2.ttot > 0.1) 2634+ 2635+ def test_run(self): 2636+ 2637+ def profiled(): 2638+ pass 2639+ 2640+ yappi.clear_stats() 2641+ try: 2642+ with yappi.run(): 2643+ profiled() 2644+ stats = yappi.get_func_stats() 2645+ finally: 2646+ yappi.clear_stats() 2647+ 2648+ self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled')) 2649+ 2650+ def test_run_recursive(self): 2651+ 2652+ def profiled(): 2653+ pass 2654+ 2655+ def not_profiled(): 2656+ pass 2657+ 2658+ yappi.clear_stats() 2659+ try: 2660+ with yappi.run(): 2661+ with yappi.run(): 2662+ profiled() 2663+ # Profiling stopped here 2664+ not_profiled() 2665+ stats = yappi.get_func_stats() 2666+ finally: 2667+ yappi.clear_stats() 2668+ 2669+ self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled')) 2670+ self.assertIsNone(utils.find_stat_by_name(stats, 'not_profiled')) 2671+ 2672+ 2673+class StatSaveScenarios(utils.YappiUnitTestCase): 2674+ 2675+ def test_pstats_conversion(self): 2676+ 2677+ def pstat_id(fs): 2678+ return (fs.module, fs.lineno, fs.name) 2679+ 2680+ def a(): 2681+ d() 2682+ 2683+ def b(): 2684+ d() 2685+ 2686+ def c(): 2687+ pass 2688+ 2689+ def d(): 2690+ pass 2691+ 2692+ _timings = {"a_1": 12, "b_1": 7, "c_1": 5, "d_1": 2} 2693+ _yappi._set_test_timings(_timings) 2694+ stats = utils.run_and_get_func_stats(a, ) 2695+ stats.strip_dirs() 2696+ stats.save("tests/a1.pstats", type="pstat") 2697+ fsa_pid = pstat_id(utils.find_stat_by_name(stats, "a")) 2698+ fsd_pid = pstat_id(utils.find_stat_by_name(stats, "d")) 2699+ yappi.clear_stats() 2700+ _yappi._set_test_timings(_timings) 2701+ stats = utils.run_and_get_func_stats(a, ) 2702+ stats.strip_dirs() 2703+ stats.save("tests/a2.pstats", type="pstat") 2704+ yappi.clear_stats() 2705+ _yappi._set_test_timings(_timings) 2706+ stats = utils.run_and_get_func_stats(b, ) 2707+ stats.strip_dirs() 2708+ stats.save("tests/b1.pstats", type="pstat") 2709+ fsb_pid = pstat_id(utils.find_stat_by_name(stats, "b")) 2710+ yappi.clear_stats() 2711+ _yappi._set_test_timings(_timings) 2712+ stats = utils.run_and_get_func_stats(c, ) 2713+ stats.strip_dirs() 2714+ stats.save("tests/c1.pstats", type="pstat") 2715+ fsc_pid = pstat_id(utils.find_stat_by_name(stats, "c")) 2716+ 2717+ # merge saved stats and check pstats values are correct 2718+ import pstats 2719+ p = pstats.Stats( 2720+ 'tests/a1.pstats', 'tests/a2.pstats', 'tests/b1.pstats', 2721+ 'tests/c1.pstats' 2722+ ) 2723+ p.strip_dirs() 2724+ # ct = ttot, tt = tsub 2725+ (cc, nc, tt, ct, callers) = p.stats[fsa_pid] 2726+ self.assertEqual(cc, nc, 2) 2727+ self.assertEqual(tt, 20) 2728+ self.assertEqual(ct, 24) 2729+ (cc, nc, tt, ct, callers) = p.stats[fsd_pid] 2730+ self.assertEqual(cc, nc, 3) 2731+ self.assertEqual(tt, 6) 2732+ self.assertEqual(ct, 6) 2733+ self.assertEqual(len(callers), 2) 2734+ (cc, nc, tt, ct) = callers[fsa_pid] 2735+ self.assertEqual(cc, nc, 2) 2736+ self.assertEqual(tt, 4) 2737+ self.assertEqual(ct, 4) 2738+ (cc, nc, tt, ct) = callers[fsb_pid] 2739+ self.assertEqual(cc, nc, 1) 2740+ self.assertEqual(tt, 2) 2741+ self.assertEqual(ct, 2) 2742+ 2743+ def test_merge_stats(self): 2744+ _timings = { 2745+ "a_1": 15, 2746+ "b_1": 14, 2747+ "c_1": 12, 2748+ "d_1": 10, 2749+ "e_1": 9, 2750+ "f_1": 7, 2751+ "g_1": 6, 2752+ "h_1": 5, 2753+ "i_1": 1 2754+ } 2755+ _yappi._set_test_timings(_timings) 2756+ 2757+ def a(): 2758+ b() 2759+ 2760+ def b(): 2761+ c() 2762+ 2763+ def c(): 2764+ d() 2765+ 2766+ def d(): 2767+ e() 2768+ 2769+ def e(): 2770+ f() 2771+ 2772+ def f(): 2773+ g() 2774+ 2775+ def g(): 2776+ h() 2777+ 2778+ def h(): 2779+ i() 2780+ 2781+ def i(): 2782+ pass 2783+ 2784+ yappi.start() 2785+ a() 2786+ a() 2787+ yappi.stop() 2788+ stats = yappi.get_func_stats() 2789+ self.assertRaises( 2790+ NotImplementedError, stats.save, "", "INVALID_SAVE_TYPE" 2791+ ) 2792+ stats.save("tests/ystats2.ys") 2793+ yappi.clear_stats() 2794+ _yappi._set_test_timings(_timings) 2795+ yappi.start() 2796+ a() 2797+ stats = yappi.get_func_stats().add("tests/ystats2.ys") 2798+ fsa = utils.find_stat_by_name(stats, "a") 2799+ fsb = utils.find_stat_by_name(stats, "b") 2800+ fsc = utils.find_stat_by_name(stats, "c") 2801+ fsd = utils.find_stat_by_name(stats, "d") 2802+ fse = utils.find_stat_by_name(stats, "e") 2803+ fsf = utils.find_stat_by_name(stats, "f") 2804+ fsg = utils.find_stat_by_name(stats, "g") 2805+ fsh = utils.find_stat_by_name(stats, "h") 2806+ fsi = utils.find_stat_by_name(stats, "i") 2807+ self.assertEqual(fsa.ttot, 45) 2808+ self.assertEqual(fsa.ncall, 3) 2809+ self.assertEqual(fsa.nactualcall, 3) 2810+ self.assertEqual(fsa.tsub, 3) 2811+ self.assertEqual(fsa.children[fsb].ttot, fsb.ttot) 2812+ self.assertEqual(fsa.children[fsb].tsub, fsb.tsub) 2813+ self.assertEqual(fsb.children[fsc].ttot, fsc.ttot) 2814+ self.assertEqual(fsb.children[fsc].tsub, fsc.tsub) 2815+ self.assertEqual(fsc.tsub, 6) 2816+ self.assertEqual(fsc.children[fsd].ttot, fsd.ttot) 2817+ self.assertEqual(fsc.children[fsd].tsub, fsd.tsub) 2818+ self.assertEqual(fsd.children[fse].ttot, fse.ttot) 2819+ self.assertEqual(fsd.children[fse].tsub, fse.tsub) 2820+ self.assertEqual(fse.children[fsf].ttot, fsf.ttot) 2821+ self.assertEqual(fse.children[fsf].tsub, fsf.tsub) 2822+ self.assertEqual(fsf.children[fsg].ttot, fsg.ttot) 2823+ self.assertEqual(fsf.children[fsg].tsub, fsg.tsub) 2824+ self.assertEqual(fsg.ttot, 18) 2825+ self.assertEqual(fsg.tsub, 3) 2826+ self.assertEqual(fsg.children[fsh].ttot, fsh.ttot) 2827+ self.assertEqual(fsg.children[fsh].tsub, fsh.tsub) 2828+ self.assertEqual(fsh.ttot, 15) 2829+ self.assertEqual(fsh.tsub, 12) 2830+ self.assertEqual(fsh.tavg, 5) 2831+ self.assertEqual(fsh.children[fsi].ttot, fsi.ttot) 2832+ self.assertEqual(fsh.children[fsi].tsub, fsi.tsub) 2833+ #stats.debug_print() 2834+ 2835+ def test_merge_multithreaded_stats(self): 2836+ import _yappi 2837+ timings = {"a_1": 2, "b_1": 1} 2838+ _yappi._set_test_timings(timings) 2839+ 2840+ def a(): 2841+ pass 2842+ 2843+ def b(): 2844+ pass 2845+ 2846+ yappi.start() 2847+ t = threading.Thread(target=a) 2848+ t.start() 2849+ t.join() 2850+ t = threading.Thread(target=b) 2851+ t.start() 2852+ t.join() 2853+ yappi.get_func_stats().save("tests/ystats1.ys") 2854+ yappi.clear_stats() 2855+ _yappi._set_test_timings(timings) 2856+ self.assertEqual(len(yappi.get_func_stats()), 0) 2857+ self.assertEqual(len(yappi.get_thread_stats()), 1) 2858+ t = threading.Thread(target=a) 2859+ t.start() 2860+ t.join() 2861+ 2862+ self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0) 2863+ self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1) 2864+ yappi.get_func_stats().save("tests/ystats2.ys") 2865+ 2866+ stats = yappi.YFuncStats([ 2867+ "tests/ystats1.ys", 2868+ "tests/ystats2.ys", 2869+ ]) 2870+ fsa = utils.find_stat_by_name(stats, "a") 2871+ fsb = utils.find_stat_by_name(stats, "b") 2872+ self.assertEqual(fsa.ncall, 2) 2873+ self.assertEqual(fsb.ncall, 1) 2874+ self.assertEqual(fsa.tsub, fsa.ttot, 4) 2875+ self.assertEqual(fsb.tsub, fsb.ttot, 1) 2876+ 2877+ def test_merge_load_different_clock_types(self): 2878+ yappi.start(builtins=True) 2879+ 2880+ def a(): 2881+ b() 2882+ 2883+ def b(): 2884+ c() 2885+ 2886+ def c(): 2887+ pass 2888+ 2889+ t = threading.Thread(target=a) 2890+ t.start() 2891+ t.join() 2892+ yappi.get_func_stats().sort("name", "asc").save("tests/ystats1.ys") 2893+ yappi.stop() 2894+ yappi.clear_stats() 2895+ yappi.start(builtins=False) 2896+ t = threading.Thread(target=a) 2897+ t.start() 2898+ t.join() 2899+ yappi.get_func_stats().save("tests/ystats2.ys") 2900+ yappi.stop() 2901+ self.assertRaises(_yappi.error, yappi.set_clock_type, "wall") 2902+ yappi.clear_stats() 2903+ yappi.set_clock_type("wall") 2904+ yappi.start() 2905+ t = threading.Thread(target=a) 2906+ t.start() 2907+ t.join() 2908+ yappi.get_func_stats().save("tests/ystats3.ys") 2909+ self.assertRaises( 2910+ yappi.YappiError, 2911+ yappi.YFuncStats().add("tests/ystats1.ys").add, "tests/ystats3.ys" 2912+ ) 2913+ stats = yappi.YFuncStats(["tests/ystats1.ys", 2914+ "tests/ystats2.ys"]).sort("name") 2915+ fsa = utils.find_stat_by_name(stats, "a") 2916+ fsb = utils.find_stat_by_name(stats, "b") 2917+ fsc = utils.find_stat_by_name(stats, "c") 2918+ self.assertEqual(fsa.ncall, 2) 2919+ self.assertEqual(fsa.ncall, fsb.ncall, fsc.ncall) 2920+ 2921+ def test_merge_aabab_aabbc(self): 2922+ _timings = { 2923+ "a_1": 15, 2924+ "a_2": 14, 2925+ "b_1": 12, 2926+ "a_3": 10, 2927+ "b_2": 9, 2928+ "c_1": 4 2929+ } 2930+ _yappi._set_test_timings(_timings) 2931+ 2932+ def a(): 2933+ if self._ncall == 1: 2934+ self._ncall += 1 2935+ a() 2936+ elif self._ncall == 5: 2937+ self._ncall += 1 2938+ a() 2939+ else: 2940+ b() 2941+ 2942+ def b(): 2943+ if self._ncall == 2: 2944+ self._ncall += 1 2945+ a() 2946+ elif self._ncall == 6: 2947+ self._ncall += 1 2948+ b() 2949+ elif self._ncall == 7: 2950+ c() 2951+ else: 2952+ return 2953+ 2954+ def c(): 2955+ pass 2956+ 2957+ self._ncall = 1 2958+ stats = utils.run_and_get_func_stats(a, ) 2959+ stats.save("tests/ystats1.ys") 2960+ yappi.clear_stats() 2961+ _yappi._set_test_timings(_timings) 2962+ #stats.print_all() 2963+ 2964+ self._ncall = 5 2965+ stats = utils.run_and_get_func_stats(a, ) 2966+ stats.save("tests/ystats2.ys") 2967+ 2968+ #stats.print_all() 2969+ 2970+ def a(): # same name but another function(code object) 2971+ pass 2972+ 2973+ yappi.start() 2974+ a() 2975+ stats = yappi.get_func_stats().add( 2976+ ["tests/ystats1.ys", "tests/ystats2.ys"] 2977+ ) 2978+ #stats.print_all() 2979+ self.assertEqual(len(stats), 4) 2980+ 2981+ fsa = None 2982+ for stat in stats: 2983+ if stat.name == "a" and stat.ttot == 45: 2984+ fsa = stat 2985+ break 2986+ self.assertTrue(fsa is not None) 2987+ 2988+ self.assertEqual(fsa.ncall, 7) 2989+ self.assertEqual(fsa.nactualcall, 3) 2990+ self.assertEqual(fsa.ttot, 45) 2991+ self.assertEqual(fsa.tsub, 10) 2992+ fsb = utils.find_stat_by_name(stats, "b") 2993+ fsc = utils.find_stat_by_name(stats, "c") 2994+ self.assertEqual(fsb.ncall, 6) 2995+ self.assertEqual(fsb.nactualcall, 3) 2996+ self.assertEqual(fsb.ttot, 36) 2997+ self.assertEqual(fsb.tsub, 27) 2998+ self.assertEqual(fsb.tavg, 6) 2999+ self.assertEqual(fsc.ttot, 8) 3000+ self.assertEqual(fsc.tsub, 8) 3001+ self.assertEqual(fsc.tavg, 4) 3002+ self.assertEqual(fsc.nactualcall, fsc.ncall, 2) 3003+ 3004+ 3005+class MultithreadedScenarios(utils.YappiUnitTestCase): 3006+ 3007+ def test_issue_32(self): 3008+ ''' 3009+ Start yappi from different thread and we get Internal Error(15) as 3010+ the current_ctx_id() called while enumerating the threads in start() 3011+ and as it does not swap to the enumerated ThreadState* the THreadState_GetDict() 3012+ returns wrong object and thus sets an invalid id for the _ctx structure. 3013+ 3014+ When this issue happens multiple Threads have same tid as the internal ts_ptr 3015+ will be same for different contexts. So, let's see if that happens 3016+ ''' 3017+ 3018+ def foo(): 3019+ time.sleep(0.2) 3020+ 3021+ def bar(): 3022+ time.sleep(0.1) 3023+ 3024+ def thread_func(): 3025+ yappi.set_clock_type("wall") 3026+ yappi.start() 3027+ 3028+ bar() 3029+ 3030+ t = threading.Thread(target=thread_func) 3031+ t.start() 3032+ t.join() 3033+ 3034+ foo() 3035+ 3036+ yappi.stop() 3037+ 3038+ thread_ids = set() 3039+ for tstat in yappi.get_thread_stats(): 3040+ self.assertTrue(tstat.tid not in thread_ids) 3041+ thread_ids.add(tstat.tid) 3042+ 3043+ def test_subsequent_profile(self): 3044+ WORKER_COUNT = 5 3045+ 3046+ def a(): 3047+ pass 3048+ 3049+ def b(): 3050+ pass 3051+ 3052+ def c(): 3053+ pass 3054+ 3055+ _timings = { 3056+ "a_1": 3, 3057+ "b_1": 2, 3058+ "c_1": 1, 3059+ } 3060+ 3061+ yappi.start() 3062+ 3063+ def g(): 3064+ pass 3065+ 3066+ g() 3067+ yappi.stop() 3068+ yappi.clear_stats() 3069+ _yappi._set_test_timings(_timings) 3070+ yappi.start() 3071+ 3072+ _dummy = [] 3073+ for i in range(WORKER_COUNT): 3074+ t = threading.Thread(target=a) 3075+ t.start() 3076+ t.join() 3077+ for i in range(WORKER_COUNT): 3078+ t = threading.Thread(target=b) 3079+ t.start() 3080+ _dummy.append(t) 3081+ t.join() 3082+ for i in range(WORKER_COUNT): 3083+ t = threading.Thread(target=a) 3084+ t.start() 3085+ t.join() 3086+ for i in range(WORKER_COUNT): 3087+ t = threading.Thread(target=c) 3088+ t.start() 3089+ t.join() 3090+ yappi.stop() 3091+ yappi.start() 3092+ 3093+ def f(): 3094+ pass 3095+ 3096+ f() 3097+ stats = yappi.get_func_stats() 3098+ fsa = utils.find_stat_by_name(stats, 'a') 3099+ fsb = utils.find_stat_by_name(stats, 'b') 3100+ fsc = utils.find_stat_by_name(stats, 'c') 3101+ self.assertEqual(fsa.ncall, 10) 3102+ self.assertEqual(fsb.ncall, 5) 3103+ self.assertEqual(fsc.ncall, 5) 3104+ self.assertEqual(fsa.ttot, fsa.tsub, 30) 3105+ self.assertEqual(fsb.ttot, fsb.tsub, 10) 3106+ self.assertEqual(fsc.ttot, fsc.tsub, 5) 3107+ 3108+ # MACOSx optimizes by only creating one worker thread 3109+ self.assertTrue(len(yappi.get_thread_stats()) >= 2) 3110+ 3111+ def test_basic(self): 3112+ yappi.set_clock_type('wall') 3113+ 3114+ def dummy(): 3115+ pass 3116+ 3117+ def a(): 3118+ time.sleep(0.2) 3119+ 3120+ class Worker1(threading.Thread): 3121+ 3122+ def a(self): 3123+ time.sleep(0.3) 3124+ 3125+ def run(self): 3126+ self.a() 3127+ 3128+ yappi.start(builtins=False, profile_threads=True) 3129+ 3130+ c = Worker1() 3131+ c.start() 3132+ c.join() 3133+ a() 3134+ stats = yappi.get_func_stats() 3135+ fsa1 = utils.find_stat_by_name(stats, 'Worker1.a') 3136+ fsa2 = utils.find_stat_by_name(stats, 'a') 3137+ self.assertTrue(fsa1 is not None) 3138+ self.assertTrue(fsa2 is not None) 3139+ self.assertTrue(fsa1.ttot > 0.2) 3140+ self.assertTrue(fsa2.ttot > 0.1) 3141+ tstats = yappi.get_thread_stats() 3142+ self.assertEqual(len(tstats), 2) 3143+ tsa = utils.find_stat_by_name(tstats, 'Worker1') 3144+ tsm = utils.find_stat_by_name(tstats, '_MainThread') 3145+ dummy() # call dummy to force ctx name to be retrieved again. 3146+ self.assertTrue(tsa is not None) 3147+ # TODO: I put dummy() to fix below, remove the comments after a while. 3148+ self.assertTrue( # FIX: I see this fails sometimes? 3149+ tsm is not None, 3150+ 'Could not find "_MainThread". Found: %s' % (', '.join(utils.get_stat_names(tstats)))) 3151+ 3152+ def test_ctx_stats(self): 3153+ from threading import Thread 3154+ DUMMY_WORKER_COUNT = 5 3155+ yappi.start() 3156+ 3157+ class DummyThread(Thread): 3158+ pass 3159+ 3160+ def dummy(): 3161+ pass 3162+ 3163+ def dummy_worker(): 3164+ pass 3165+ 3166+ for i in range(DUMMY_WORKER_COUNT): 3167+ t = DummyThread(target=dummy_worker) 3168+ t.start() 3169+ t.join() 3170+ yappi.stop() 3171+ stats = yappi.get_thread_stats() 3172+ tsa = utils.find_stat_by_name(stats, "DummyThread") 3173+ self.assertTrue(tsa is not None) 3174+ yappi.clear_stats() 3175+ time.sleep(1.0) 3176+ _timings = { 3177+ "a_1": 6, 3178+ "b_1": 5, 3179+ "c_1": 3, 3180+ "d_1": 1, 3181+ "a_2": 4, 3182+ "b_2": 3, 3183+ "c_2": 2, 3184+ "d_2": 1 3185+ } 3186+ _yappi._set_test_timings(_timings) 3187+ 3188+ class Thread1(Thread): 3189+ pass 3190+ 3191+ class Thread2(Thread): 3192+ pass 3193+ 3194+ def a(): 3195+ b() 3196+ 3197+ def b(): 3198+ c() 3199+ 3200+ def c(): 3201+ d() 3202+ 3203+ def d(): 3204+ time.sleep(0.6) 3205+ 3206+ yappi.set_clock_type("wall") 3207+ yappi.start() 3208+ t1 = Thread1(target=a) 3209+ t1.start() 3210+ t2 = Thread2(target=a) 3211+ t2.start() 3212+ t1.join() 3213+ t2.join() 3214+ stats = yappi.get_thread_stats() 3215+ 3216+ # the fist clear_stats clears the context table? 3217+ tsa = utils.find_stat_by_name(stats, "DummyThread") 3218+ self.assertTrue(tsa is None) 3219+ 3220+ tst1 = utils.find_stat_by_name(stats, "Thread1") 3221+ tst2 = utils.find_stat_by_name(stats, "Thread2") 3222+ tsmain = utils.find_stat_by_name(stats, "_MainThread") 3223+ dummy() # call dummy to force ctx name to be retrieved again. 3224+ self.assertTrue(len(stats) == 3) 3225+ self.assertTrue(tst1 is not None) 3226+ self.assertTrue(tst2 is not None) 3227+ # TODO: I put dummy() to fix below, remove the comments after a while. 3228+ self.assertTrue( # FIX: I see this fails sometimes 3229+ tsmain is not None, 3230+ 'Could not find "_MainThread". Found: %s' % (', '.join(utils.get_stat_names(stats)))) 3231+ self.assertTrue(1.0 > tst2.ttot >= 0.5) 3232+ self.assertTrue(1.0 > tst1.ttot >= 0.5) 3233+ 3234+ # test sorting of the ctx stats 3235+ stats = stats.sort("totaltime", "desc") 3236+ prev_stat = None 3237+ for stat in stats: 3238+ if prev_stat: 3239+ self.assertTrue(prev_stat.ttot >= stat.ttot) 3240+ prev_stat = stat 3241+ stats = stats.sort("totaltime", "asc") 3242+ prev_stat = None 3243+ for stat in stats: 3244+ if prev_stat: 3245+ self.assertTrue(prev_stat.ttot <= stat.ttot) 3246+ prev_stat = stat 3247+ stats = stats.sort("schedcount", "desc") 3248+ prev_stat = None 3249+ for stat in stats: 3250+ if prev_stat: 3251+ self.assertTrue(prev_stat.sched_count >= stat.sched_count) 3252+ prev_stat = stat 3253+ stats = stats.sort("name", "desc") 3254+ prev_stat = None 3255+ for stat in stats: 3256+ if prev_stat: 3257+ self.assertTrue(prev_stat.name.lower() >= stat.name.lower()) 3258+ prev_stat = stat 3259+ self.assertRaises( 3260+ yappi.YappiError, stats.sort, "invalid_thread_sorttype_arg" 3261+ ) 3262+ self.assertRaises( 3263+ yappi.YappiError, stats.sort, "invalid_thread_sortorder_arg" 3264+ ) 3265+ 3266+ def test_ctx_stats_cpu(self): 3267+ 3268+ def get_thread_name(): 3269+ try: 3270+ return threading.current_thread().name 3271+ except AttributeError: 3272+ return "Anonymous" 3273+ 3274+ def burn_cpu(sec): 3275+ t0 = yappi.get_clock_time() 3276+ elapsed = 0 3277+ while (elapsed < sec): 3278+ for _ in range(1000): 3279+ pass 3280+ elapsed = yappi.get_clock_time() - t0 3281+ 3282+ def test(): 3283+ 3284+ ts = [] 3285+ for i in (0.01, 0.05, 0.1): 3286+ t = threading.Thread(target=burn_cpu, args=(i, )) 3287+ t.name = "burn_cpu-%s" % str(i) 3288+ t.start() 3289+ ts.append(t) 3290+ for t in ts: 3291+ t.join() 3292+ 3293+ yappi.set_clock_type("cpu") 3294+ yappi.set_context_name_callback(get_thread_name) 3295+ 3296+ yappi.start() 3297+ 3298+ test() 3299+ 3300+ yappi.stop() 3301+ 3302+ tstats = yappi.get_thread_stats() 3303+ r1 = ''' 3304+ burn_cpu-0.1 3 123145356058624 0.100105 8 3305+ burn_cpu-0.05 2 123145361313792 0.050149 8 3306+ burn_cpu-0.01 1 123145356058624 0.010127 2 3307+ MainThread 0 4321620864 0.001632 6 3308+ ''' 3309+ self.assert_ctx_stats_almost_equal(r1, tstats) 3310+ 3311+ def test_producer_consumer_with_queues(self): 3312+ # we currently just stress yappi, no functionality test is done here. 3313+ yappi.start() 3314+ if utils.is_py3x(): 3315+ from queue import Queue 3316+ else: 3317+ from Queue import Queue 3318+ from threading import Thread 3319+ WORKER_THREAD_COUNT = 50 3320+ WORK_ITEM_COUNT = 2000 3321+ 3322+ def worker(): 3323+ while True: 3324+ item = q.get() 3325+ # do the work with item 3326+ q.task_done() 3327+ 3328+ q = Queue() 3329+ for i in range(WORKER_THREAD_COUNT): 3330+ t = Thread(target=worker) 3331+ t.daemon = True 3332+ t.start() 3333+ 3334+ for item in range(WORK_ITEM_COUNT): 3335+ q.put(item) 3336+ q.join() # block until all tasks are done 3337+ #yappi.get_func_stats().sort("callcount").print_all() 3338+ yappi.stop() 3339+ 3340+ def test_temporary_lock_waiting(self): 3341+ yappi.start() 3342+ _lock = threading.Lock() 3343+ 3344+ def worker(): 3345+ _lock.acquire() 3346+ try: 3347+ time.sleep(1.0) 3348+ finally: 3349+ _lock.release() 3350+ 3351+ t1 = threading.Thread(target=worker) 3352+ t2 = threading.Thread(target=worker) 3353+ t1.start() 3354+ t2.start() 3355+ t1.join() 3356+ t2.join() 3357+ #yappi.get_func_stats().sort("callcount").print_all() 3358+ yappi.stop() 3359+ 3360+ @unittest.skipIf(os.name != "posix", "requires Posix compliant OS") 3361+ def test_signals_with_blocking_calls(self): 3362+ import signal, os, time 3363+ 3364+ # just to verify if signal is handled correctly and stats/yappi are not corrupted. 3365+ def handler(signum, frame): 3366+ raise Exception("Signal handler executed!") 3367+ 3368+ yappi.start() 3369+ signal.signal(signal.SIGALRM, handler) 3370+ signal.alarm(1) 3371+ self.assertRaises(Exception, time.sleep, 2) 3372+ stats = yappi.get_func_stats() 3373+ fsh = utils.find_stat_by_name(stats, "handler") 3374+ self.assertTrue(fsh is not None) 3375+ 3376+ @unittest.skipIf(not sys.version_info >= (3, 2), "requires Python 3.2") 3377+ def test_concurrent_futures(self): 3378+ yappi.start() 3379+ from concurrent.futures import ThreadPoolExecutor 3380+ with ThreadPoolExecutor(max_workers=5) as executor: 3381+ f = executor.submit(pow, 5, 2) 3382+ self.assertEqual(f.result(), 25) 3383+ time.sleep(1.0) 3384+ yappi.stop() 3385+ 3386+ @unittest.skipIf(not sys.version_info >= (3, 2), "requires Python 3.2") 3387+ def test_barrier(self): 3388+ yappi.start() 3389+ b = threading.Barrier(2, timeout=1) 3390+ 3391+ def worker(): 3392+ try: 3393+ b.wait() 3394+ except threading.BrokenBarrierError: 3395+ pass 3396+ except Exception: 3397+ raise Exception("BrokenBarrierError not raised") 3398+ 3399+ t1 = threading.Thread(target=worker) 3400+ t1.start() 3401+ #b.wait() 3402+ t1.join() 3403+ yappi.stop() 3404+ 3405+ 3406+class NonRecursiveFunctions(utils.YappiUnitTestCase): 3407+ 3408+ def test_abcd(self): 3409+ _timings = {"a_1": 6, "b_1": 5, "c_1": 3, "d_1": 1} 3410+ _yappi._set_test_timings(_timings) 3411+ 3412+ def a(): 3413+ b() 3414+ 3415+ def b(): 3416+ c() 3417+ 3418+ def c(): 3419+ d() 3420+ 3421+ def d(): 3422+ pass 3423+ 3424+ stats = utils.run_and_get_func_stats(a) 3425+ fsa = utils.find_stat_by_name(stats, 'a') 3426+ fsb = utils.find_stat_by_name(stats, 'b') 3427+ fsc = utils.find_stat_by_name(stats, 'c') 3428+ fsd = utils.find_stat_by_name(stats, 'd') 3429+ cfsab = fsa.children[fsb] 3430+ cfsbc = fsb.children[fsc] 3431+ cfscd = fsc.children[fsd] 3432+ 3433+ self.assertEqual(fsa.ttot, 6) 3434+ self.assertEqual(fsa.tsub, 1) 3435+ self.assertEqual(fsb.ttot, 5) 3436+ self.assertEqual(fsb.tsub, 2) 3437+ self.assertEqual(fsc.ttot, 3) 3438+ self.assertEqual(fsc.tsub, 2) 3439+ self.assertEqual(fsd.ttot, 1) 3440+ self.assertEqual(fsd.tsub, 1) 3441+ self.assertEqual(cfsab.ttot, 5) 3442+ self.assertEqual(cfsab.tsub, 2) 3443+ self.assertEqual(cfsbc.ttot, 3) 3444+ self.assertEqual(cfsbc.tsub, 2) 3445+ self.assertEqual(cfscd.ttot, 1) 3446+ self.assertEqual(cfscd.tsub, 1) 3447+ 3448+ def test_stop_in_middle(self): 3449+ _timings = {"a_1": 6, "b_1": 4} 3450+ _yappi._set_test_timings(_timings) 3451+ 3452+ def a(): 3453+ b() 3454+ yappi.stop() 3455+ 3456+ def b(): 3457+ time.sleep(0.2) 3458+ 3459+ yappi.start() 3460+ a() 3461+ stats = yappi.get_func_stats() 3462+ fsa = utils.find_stat_by_name(stats, 'a') 3463+ fsb = utils.find_stat_by_name(stats, 'b') 3464+ 3465+ self.assertEqual(fsa.ncall, 1) 3466+ self.assertEqual(fsa.nactualcall, 0) 3467+ self.assertEqual(fsa.ttot, 0) # no call_leave called 3468+ self.assertEqual(fsa.tsub, 0) # no call_leave called 3469+ self.assertEqual(fsb.ttot, 4) 3470+ 3471+ 3472+class RecursiveFunctions(utils.YappiUnitTestCase): 3473+ 3474+ def test_fibonacci(self): 3475+ 3476+ def fib(n): 3477+ if n > 1: 3478+ return fib(n - 1) + fib(n - 2) 3479+ else: 3480+ return n 3481+ 3482+ stats = utils.run_and_get_func_stats(fib, 22) 3483+ fs = utils.find_stat_by_name(stats, 'fib') 3484+ self.assertEqual(fs.ncall, 57313) 3485+ self.assertEqual(fs.ttot, fs.tsub) 3486+ 3487+ def test_abcadc(self): 3488+ _timings = { 3489+ "a_1": 20, 3490+ "b_1": 19, 3491+ "c_1": 17, 3492+ "a_2": 13, 3493+ "d_1": 12, 3494+ "c_2": 10, 3495+ "a_3": 5 3496+ } 3497+ _yappi._set_test_timings(_timings) 3498+ 3499+ def a(n): 3500+ if n == 3: 3501+ return 3502+ if n == 1 + 1: 3503+ d(n) 3504+ else: 3505+ b(n) 3506+ 3507+ def b(n): 3508+ c(n) 3509+ 3510+ def c(n): 3511+ a(n + 1) 3512+ 3513+ def d(n): 3514+ c(n) 3515+ 3516+ stats = utils.run_and_get_func_stats(a, 1) 3517+ fsa = utils.find_stat_by_name(stats, 'a') 3518+ fsb = utils.find_stat_by_name(stats, 'b') 3519+ fsc = utils.find_stat_by_name(stats, 'c') 3520+ fsd = utils.find_stat_by_name(stats, 'd') 3521+ self.assertEqual(fsa.ncall, 3) 3522+ self.assertEqual(fsa.nactualcall, 1) 3523+ self.assertEqual(fsa.ttot, 20) 3524+ self.assertEqual(fsa.tsub, 7) 3525+ self.assertEqual(fsb.ttot, 19) 3526+ self.assertEqual(fsb.tsub, 2) 3527+ self.assertEqual(fsc.ttot, 17) 3528+ self.assertEqual(fsc.tsub, 9) 3529+ self.assertEqual(fsd.ttot, 12) 3530+ self.assertEqual(fsd.tsub, 2) 3531+ cfsca = fsc.children[fsa] 3532+ self.assertEqual(cfsca.nactualcall, 0) 3533+ self.assertEqual(cfsca.ncall, 2) 3534+ self.assertEqual(cfsca.ttot, 13) 3535+ self.assertEqual(cfsca.tsub, 6) 3536+ 3537+ def test_aaaa(self): 3538+ _timings = {"d_1": 9, "d_2": 7, "d_3": 3, "d_4": 2} 3539+ _yappi._set_test_timings(_timings) 3540+ 3541+ def d(n): 3542+ if n == 3: 3543+ return 3544+ d(n + 1) 3545+ 3546+ stats = utils.run_and_get_func_stats(d, 0) 3547+ fsd = utils.find_stat_by_name(stats, 'd') 3548+ self.assertEqual(fsd.ncall, 4) 3549+ self.assertEqual(fsd.nactualcall, 1) 3550+ self.assertEqual(fsd.ttot, 9) 3551+ self.assertEqual(fsd.tsub, 9) 3552+ cfsdd = fsd.children[fsd] 3553+ self.assertEqual(cfsdd.ttot, 7) 3554+ self.assertEqual(cfsdd.tsub, 7) 3555+ self.assertEqual(cfsdd.ncall, 3) 3556+ self.assertEqual(cfsdd.nactualcall, 0) 3557+ 3558+ def test_abcabc(self): 3559+ _timings = { 3560+ "a_1": 20, 3561+ "b_1": 19, 3562+ "c_1": 17, 3563+ "a_2": 13, 3564+ "b_2": 11, 3565+ "c_2": 9, 3566+ "a_3": 6 3567+ } 3568+ _yappi._set_test_timings(_timings) 3569+ 3570+ def a(n): 3571+ if n == 3: 3572+ return 3573+ else: 3574+ b(n) 3575+ 3576+ def b(n): 3577+ c(n) 3578+ 3579+ def c(n): 3580+ a(n + 1) 3581+ 3582+ stats = utils.run_and_get_func_stats(a, 1) 3583+ fsa = utils.find_stat_by_name(stats, 'a') 3584+ fsb = utils.find_stat_by_name(stats, 'b') 3585+ fsc = utils.find_stat_by_name(stats, 'c') 3586+ self.assertEqual(fsa.ncall, 3) 3587+ self.assertEqual(fsa.nactualcall, 1) 3588+ self.assertEqual(fsa.ttot, 20) 3589+ self.assertEqual(fsa.tsub, 9) 3590+ self.assertEqual(fsb.ttot, 19) 3591+ self.assertEqual(fsb.tsub, 4) 3592+ self.assertEqual(fsc.ttot, 17) 3593+ self.assertEqual(fsc.tsub, 7) 3594+ cfsab = fsa.children[fsb] 3595+ cfsbc = fsb.children[fsc] 3596+ cfsca = fsc.children[fsa] 3597+ self.assertEqual(cfsab.ttot, 19) 3598+ self.assertEqual(cfsab.tsub, 4) 3599+ self.assertEqual(cfsbc.ttot, 17) 3600+ self.assertEqual(cfsbc.tsub, 7) 3601+ self.assertEqual(cfsca.ttot, 13) 3602+ self.assertEqual(cfsca.tsub, 8) 3603+ 3604+ def test_abcbca(self): 3605+ _timings = {"a_1": 10, "b_1": 9, "c_1": 7, "b_2": 4, "c_2": 2, "a_2": 1} 3606+ _yappi._set_test_timings(_timings) 3607+ self._ncall = 1 3608+ 3609+ def a(): 3610+ if self._ncall == 1: 3611+ b() 3612+ else: 3613+ return 3614+ 3615+ def b(): 3616+ c() 3617+ 3618+ def c(): 3619+ if self._ncall == 1: 3620+ self._ncall += 1 3621+ b() 3622+ else: 3623+ a() 3624+ 3625+ stats = utils.run_and_get_func_stats(a) 3626+ fsa = utils.find_stat_by_name(stats, 'a') 3627+ fsb = utils.find_stat_by_name(stats, 'b') 3628+ fsc = utils.find_stat_by_name(stats, 'c') 3629+ cfsab = fsa.children[fsb] 3630+ cfsbc = fsb.children[fsc] 3631+ cfsca = fsc.children[fsa] 3632+ self.assertEqual(fsa.ttot, 10) 3633+ self.assertEqual(fsa.tsub, 2) 3634+ self.assertEqual(fsb.ttot, 9) 3635+ self.assertEqual(fsb.tsub, 4) 3636+ self.assertEqual(fsc.ttot, 7) 3637+ self.assertEqual(fsc.tsub, 4) 3638+ self.assertEqual(cfsab.ttot, 9) 3639+ self.assertEqual(cfsab.tsub, 2) 3640+ self.assertEqual(cfsbc.ttot, 7) 3641+ self.assertEqual(cfsbc.tsub, 4) 3642+ self.assertEqual(cfsca.ttot, 1) 3643+ self.assertEqual(cfsca.tsub, 1) 3644+ self.assertEqual(cfsca.ncall, 1) 3645+ self.assertEqual(cfsca.nactualcall, 0) 3646+ 3647+ def test_aabccb(self): 3648+ _timings = { 3649+ "a_1": 13, 3650+ "a_2": 11, 3651+ "b_1": 9, 3652+ "c_1": 5, 3653+ "c_2": 3, 3654+ "b_2": 1 3655+ } 3656+ _yappi._set_test_timings(_timings) 3657+ self._ncall = 1 3658+ 3659+ def a(): 3660+ if self._ncall == 1: 3661+ self._ncall += 1 3662+ a() 3663+ else: 3664+ b() 3665+ 3666+ def b(): 3667+ if self._ncall == 3: 3668+ return 3669+ else: 3670+ c() 3671+ 3672+ def c(): 3673+ if self._ncall == 2: 3674+ self._ncall += 1 3675+ c() 3676+ else: 3677+ b() 3678+ 3679+ stats = utils.run_and_get_func_stats(a) 3680+ fsa = utils.find_stat_by_name(stats, 'a') 3681+ fsb = utils.find_stat_by_name(stats, 'b') 3682+ fsc = utils.find_stat_by_name(stats, 'c') 3683+ cfsaa = fsa.children[fsa.index] 3684+ cfsab = fsa.children[fsb] 3685+ cfsbc = fsb.children[fsc.full_name] 3686+ cfscc = fsc.children[fsc] 3687+ cfscb = fsc.children[fsb] 3688+ self.assertEqual(fsb.ttot, 9) 3689+ self.assertEqual(fsb.tsub, 5) 3690+ self.assertEqual(cfsbc.ttot, 5) 3691+ self.assertEqual(cfsbc.tsub, 2) 3692+ self.assertEqual(fsa.ttot, 13) 3693+ self.assertEqual(fsa.tsub, 4) 3694+ self.assertEqual(cfsab.ttot, 9) 3695+ self.assertEqual(cfsab.tsub, 4) 3696+ self.assertEqual(cfsaa.ttot, 11) 3697+ self.assertEqual(cfsaa.tsub, 2) 3698+ self.assertEqual(fsc.ttot, 5) 3699+ self.assertEqual(fsc.tsub, 4) 3700+ 3701+ def test_abaa(self): 3702+ _timings = {"a_1": 13, "b_1": 10, "a_2": 9, "a_3": 5} 3703+ _yappi._set_test_timings(_timings) 3704+ 3705+ self._ncall = 1 3706+ 3707+ def a(): 3708+ if self._ncall == 1: 3709+ b() 3710+ elif self._ncall == 2: 3711+ self._ncall += 1 3712+ a() 3713+ else: 3714+ return 3715+ 3716+ def b(): 3717+ self._ncall += 1 3718+ a() 3719+ 3720+ stats = utils.run_and_get_func_stats(a) 3721+ fsa = utils.find_stat_by_name(stats, 'a') 3722+ fsb = utils.find_stat_by_name(stats, 'b') 3723+ cfsaa = fsa.children[fsa] 3724+ cfsba = fsb.children[fsa] 3725+ self.assertEqual(fsb.ttot, 10) 3726+ self.assertEqual(fsb.tsub, 1) 3727+ self.assertEqual(fsa.ttot, 13) 3728+ self.assertEqual(fsa.tsub, 12) 3729+ self.assertEqual(cfsaa.ttot, 5) 3730+ self.assertEqual(cfsaa.tsub, 5) 3731+ self.assertEqual(cfsba.ttot, 9) 3732+ self.assertEqual(cfsba.tsub, 4) 3733+ 3734+ def test_aabb(self): 3735+ _timings = {"a_1": 13, "a_2": 10, "b_1": 9, "b_2": 5} 3736+ _yappi._set_test_timings(_timings) 3737+ 3738+ self._ncall = 1 3739+ 3740+ def a(): 3741+ if self._ncall == 1: 3742+ self._ncall += 1 3743+ a() 3744+ elif self._ncall == 2: 3745+ b() 3746+ else: 3747+ return 3748+ 3749+ def b(): 3750+ if self._ncall == 2: 3751+ self._ncall += 1 3752+ b() 3753+ else: 3754+ return 3755+ 3756+ stats = utils.run_and_get_func_stats(a) 3757+ fsa = utils.find_stat_by_name(stats, 'a') 3758+ fsb = utils.find_stat_by_name(stats, 'b') 3759+ cfsaa = fsa.children[fsa] 3760+ cfsab = fsa.children[fsb] 3761+ cfsbb = fsb.children[fsb] 3762+ self.assertEqual(fsa.ttot, 13) 3763+ self.assertEqual(fsa.tsub, 4) 3764+ self.assertEqual(fsb.ttot, 9) 3765+ self.assertEqual(fsb.tsub, 9) 3766+ self.assertEqual(cfsaa.ttot, 10) 3767+ self.assertEqual(cfsaa.tsub, 1) 3768+ self.assertEqual(cfsab.ttot, 9) 3769+ self.assertEqual(cfsab.tsub, 4) 3770+ self.assertEqual(cfsbb.ttot, 5) 3771+ self.assertEqual(cfsbb.tsub, 5) 3772+ 3773+ def test_abbb(self): 3774+ _timings = {"a_1": 13, "b_1": 10, "b_2": 6, "b_3": 1} 3775+ _yappi._set_test_timings(_timings) 3776+ 3777+ self._ncall = 1 3778+ 3779+ def a(): 3780+ if self._ncall == 1: 3781+ b() 3782+ 3783+ def b(): 3784+ if self._ncall == 3: 3785+ return 3786+ self._ncall += 1 3787+ b() 3788+ 3789+ stats = utils.run_and_get_func_stats(a) 3790+ fsa = utils.find_stat_by_name(stats, 'a') 3791+ fsb = utils.find_stat_by_name(stats, 'b') 3792+ cfsab = fsa.children[fsb] 3793+ cfsbb = fsb.children[fsb] 3794+ self.assertEqual(fsa.ttot, 13) 3795+ self.assertEqual(fsa.tsub, 3) 3796+ self.assertEqual(fsb.ttot, 10) 3797+ self.assertEqual(fsb.tsub, 10) 3798+ self.assertEqual(fsb.ncall, 3) 3799+ self.assertEqual(fsb.nactualcall, 1) 3800+ self.assertEqual(cfsab.ttot, 10) 3801+ self.assertEqual(cfsab.tsub, 4) 3802+ self.assertEqual(cfsbb.ttot, 6) 3803+ self.assertEqual(cfsbb.tsub, 6) 3804+ self.assertEqual(cfsbb.nactualcall, 0) 3805+ self.assertEqual(cfsbb.ncall, 2) 3806+ 3807+ def test_aaab(self): 3808+ _timings = {"a_1": 13, "a_2": 10, "a_3": 6, "b_1": 1} 3809+ _yappi._set_test_timings(_timings) 3810+ 3811+ self._ncall = 1 3812+ 3813+ def a(): 3814+ if self._ncall == 3: 3815+ b() 3816+ return 3817+ self._ncall += 1 3818+ a() 3819+ 3820+ def b(): 3821+ return 3822+ 3823+ stats = utils.run_and_get_func_stats(a) 3824+ fsa = utils.find_stat_by_name(stats, 'a') 3825+ fsb = utils.find_stat_by_name(stats, 'b') 3826+ cfsaa = fsa.children[fsa] 3827+ cfsab = fsa.children[fsb] 3828+ self.assertEqual(fsa.ttot, 13) 3829+ self.assertEqual(fsa.tsub, 12) 3830+ self.assertEqual(fsb.ttot, 1) 3831+ self.assertEqual(fsb.tsub, 1) 3832+ self.assertEqual(cfsaa.ttot, 10) 3833+ self.assertEqual(cfsaa.tsub, 9) 3834+ self.assertEqual(cfsab.ttot, 1) 3835+ self.assertEqual(cfsab.tsub, 1) 3836+ 3837+ def test_abab(self): 3838+ _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1} 3839+ _yappi._set_test_timings(_timings) 3840+ 3841+ self._ncall = 1 3842+ 3843+ def a(): 3844+ b() 3845+ 3846+ def b(): 3847+ if self._ncall == 2: 3848+ return 3849+ self._ncall += 1 3850+ a() 3851+ 3852+ stats = utils.run_and_get_func_stats(a) 3853+ fsa = utils.find_stat_by_name(stats, 'a') 3854+ fsb = utils.find_stat_by_name(stats, 'b') 3855+ cfsab = fsa.children[fsb] 3856+ cfsba = fsb.children[fsa] 3857+ self.assertEqual(fsa.ttot, 13) 3858+ self.assertEqual(fsa.tsub, 8) 3859+ self.assertEqual(fsb.ttot, 10) 3860+ self.assertEqual(fsb.tsub, 5) 3861+ self.assertEqual(cfsab.ttot, 10) 3862+ self.assertEqual(cfsab.tsub, 5) 3863+ self.assertEqual(cfsab.ncall, 2) 3864+ self.assertEqual(cfsab.nactualcall, 1) 3865+ self.assertEqual(cfsba.ttot, 6) 3866+ self.assertEqual(cfsba.tsub, 5) 3867+ 3868+ 3869+if __name__ == '__main__': 3870+ # import sys;sys.argv = ['', 'BasicUsage.test_run_as_script'] 3871+ # import sys;sys.argv = ['', 'MultithreadedScenarios.test_subsequent_profile'] 3872+ unittest.main() 3873--- a/tests/test_gevent.py 3874+++ b/tests/test_gevent.py 3875@@ -4,7 +4,7 @@ import yappi 3876 import gevent 3877 from gevent.event import Event 3878 import threading 3879-from utils import ( 3880+from .utils import ( 3881 YappiUnitTestCase, find_stat_by_name, burn_cpu, burn_io, 3882 burn_io_gevent 3883 ) 3884--- a/tests/test_hooks.py 3885+++ b/tests/test_hooks.py 3886@@ -5,7 +5,7 @@ import unittest 3887 import time 3888 3889 import yappi 3890-import utils 3891+import tests.utils as utils 3892 3893 3894 def a(): 3895--- a/tests/test_tags.py 3896+++ b/tests/test_tags.py 3897@@ -2,7 +2,7 @@ import unittest 3898 import yappi 3899 import threading 3900 import time 3901-from utils import YappiUnitTestCase, find_stat_by_name, burn_cpu, burn_io 3902+from .utils import YappiUnitTestCase, find_stat_by_name, burn_cpu, burn_io 3903 3904 3905 class MultiThreadTests(YappiUnitTestCase): 3906