B ÃÌ4]A!ã@sÐdZddlZddlZddlZddlZddlZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z y ddlZWnek r˜dZYnXdZdZGd d „d eƒZddd„Zejddd„ƒZdS)z§Profiling support for unit and performance tests. These are special purpose profiling methods which operate in a more fine-grained way than nose's profiling plugin. éNé)Úconfig)Ú gc_collecté)Újython)Úpypy)Úupdate_wrapper)Úwin32c@sTeZdZdZdd„Zedd„ƒZdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dS)ÚProfileStatsFilez°"Store per-platform/fn profiling results in a file. We're still targeting Py2.5, 2.4 on 0.7 with no dependencies, so no json lib :( need to roll something silly cCsztjdk otjj|_|jp*tjdk o*tjj|_tj |¡|_ tj  |j ¡d|_ t   dd„¡|_| ¡|jrv| ¡dS)NéÿÿÿÿcSs t t¡S)N)Ú collectionsÚ defaultdictÚdict©rrúO/opt/alt/python37/lib64/python3.7/site-packages/sqlalchemy/testing/profiling.pyÚ:óz+ProfileStatsFile.__init__..)rZoptionsZforce_write_profilesÚ force_writeZwrite_profilesÚwriteÚosÚpathÚabspathÚfnameÚsplitÚ short_fnamer r ÚdataÚ_readÚ_write)ÚselfÚfilenamerrrÚ__init__0s zProfileStatsFile.__init__cCsªtjjdtjj}d dd„tjdd…Dƒ¡}|g}| |¡trP| d¡t r^| d¡t rl| d ¡| tjj j r~d nd ¡tj  ¡}| |ršd pœd ¡d |¡S)NÚ_Ú.cSsg|] }t|ƒ‘qSr)Ústr)Ú.0Úvrrrú Hsz1ProfileStatsFile.platform_key..rrrrÚwinZ nativeunicodeZ dbapiunicodeZ cextensionsZ nocextensions)rZdbÚnameZdriverÚjoinÚsysÚ version_infoÚappendrrr ZdialectZconvert_unicodeZ requirementsZ_has_cextensions)rZ dbapi_keyZ py_versionZplatform_tokensZ _has_cextrrrÚ platform_keyBs      zProfileStatsFile.platform_keycCst}||jko|j|j|kS)N)Ú _current_testrr-)rÚtest_keyrrrÚ has_stats[szProfileStatsFile.has_statsc Cs¦t}|j|}||j}d|kr.g|d<}n|d}d|krLd|d<}n|d}t|ƒ|k}|s‚| |¡|jr|| ¡d}n|d||f}|dd7<|S)NÚcountsÚ current_countrÚlinenor)r.rr-Úlenr,rr) rÚ callcountr/Úper_fnÚ per_platformr1r2Z has_countÚresultrrrr8as$    zProfileStatsFile.resultcCs\t}|j|}||j}|d}|d}|t|ƒkrB|||d<n||d<|jrX| ¡dS)Nr1r2rr )r.rr-r4rr)rr5r/r6r7r1r2rrrÚreplace|s   zProfileStatsFile.replacecCs d|jS)Na # %s # This file is written out on a per-environment basis. # For each test in aaa_profiling, the corresponding function and # environment is located within this file. If it doesn't exist, # the test is skipped. # If a callcount does exist, it is compared to what we received. # assertions are raised if the counts do not match. # # To add a new callcount test, apply the function_call_count # decorator and re-run the tests using the --write-profiles # option - this file will be rewritten including the new count. # )r)rrrrÚ_header‰szProfileStatsFile._headerc Cs®yt|jƒ}Wntk r"dSXx|t|ƒD]p\}}| ¡}|r.| d¡rNq.| ¡\}}}|j|}||}dd„| d¡Dƒ} | |d<|d|d<d|d <q.W| ¡dS) Nú#cSsg|] }t|ƒ‘qSr)Úint)r$Úcountrrrr&©sz*ProfileStatsFile._read..ú,r1rr3rr2) ÚopenrÚIOErrorÚ enumerateÚstripÚ startswithrrÚclose) rÚ profile_fr3Úliner/r-r1r6r7Úcrrrrœs    zProfileStatsFile._readcCs¦td|jƒt|jdƒ}| | ¡¡xpt|jƒD]b}|j|}| d|¡xDt|ƒD]8}||}d dd„|dDƒ¡}| d|||f¡qZWq4W| ¡dS) NzWriting profile file %sÚwz # TEST: %s r>css|]}t|ƒVqdS)N)r#)r$r=rrrú ¹sz*ProfileStatsFile._write..r1z %s %s %s ) Úprintrr?rr:Úsortedrr)rD)rrEr/r6r-r7rGrrrr¯s  zProfileStatsFile._writeN) Ú__name__Ú __module__Ú __qualname__Ú__doc__r Úpropertyr-r0r8r9r:rrrrrrr (s  r çš™™™™™©?cs‡fdd„}|S)a©Assert a target for a test case's function call count. The main purpose of this assertion is to detect changes in callcounts for various functions - the actual number is not as important. Callcounts are stored in a file keyed to Python version and OS platform information. This file is generated automatically for new tests, and versioned so that unexpected changes in callcounts will be detected. cs‡‡fdd„}t|ˆƒS)Nc s tˆd ˆ||ŽSQRXdS)N)Úvariance)Úcount_functions)ÚargsÚkw)ÚfnrRrrÚwrapÊs z3function_call_count..decorate..wrap)r)rVrW)rR)rVrÚdecorateÉsz%function_call_count..decorater)rRrXr)rRrÚfunction_call_count¾s rYc cs tdkrt d¡‚t ¡s0tjs0t dtj¡tƒt  ¡}|  ¡dV|  ¡t j |tjd}|j}t |¡}|dkr‚d}n|\}}td||fƒ| d¡| ¡|rt||ƒ}t||ƒ|k}|sÚtjrtjrìt |¡ntd||d|tjfƒ‚dS)NzcProfile is not installedzŒNo profiling stats available on this platform for this function. Run tests with --write-profiles to add statistics to %s for this platform.)ÚstreamzPstats calls: %d Expected %sZ cumulativez†Adjusted function call count %s not within %s%% of expected %s, platform %s. Rerun with --write-profiles to regenerate this callcount.éd)ÚcProfilerZ_skip_test_exceptionÚ_profile_statsr0rZ skip_testrrZProfileZenableZdisableÚpstatsZStatsr*ÚstdoutZ total_callsr8rJZ sort_statsZ print_statsr<Úabsrr9ÚAssertionErrorr-) rRZprZstatsr5ZexpectedZexpected_countZline_noZdevianceZfailedrrrrSÓs@       rS)rQ)rQ)rOr Ú contextlibrr^r*ÚrÚutilrrrrr r\Ú ImportErrorr.r]Úobjectr rYÚcontextmanagerrSrrrrÚ s,