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