'L icZdZddlmZddlmZddlZddlZddlZddlZddl m cm Z ddl mZddl mZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZddlmZddl Z edZ!d*dZ"d+dZ#dddgidgdidZ$e$djKe$d<e#e$de$de$de$d<GddZ& d,dZ'e jPd-dZ)e jPd-d Z*d.d!Z+e jPd"#d-d$Z,d/d%Z-d0d&Z.d0d'Z/d1d(Z0Gd)dZ1y)2aReport test results in JUnit-XML format, for use with Jenkins and build integration servers. Based on initial code from Ross Lawley. Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd ) annotations)CallableN)nodes)timing) ExceptionRepr)ReprFileLocation)Config) filename_arg)Parser)FixtureRequest) TestReport)StashKey)TerminalReporterLogXMLcNdd}d}tj||t|S)a!Visually escape invalid XML characters. For example, transforms 'hello\aworld\b' into 'hello#x07world#x08' Note that the #xABs are *not* XML escapes - missing the ampersand «. The idea is to escape visually for the user rather than for XML itself. cVt|j}|dkrd|dSd|dS)Nz#x02X04X)ordgroup)matchobjis V/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/_pytest/junitxml.pyreplzbin_xml_escape..repl0s6  ! 9#w< #w< u [^ -~€-퟿-�က0-ჿff])rz re.Match[str]returnstr)resubr)argrillegal_xml_res rbin_xml_escaper#%s+  W 66.$C 11rci}|jD]I\}}|jD]1\}}t|tstt |||z||<3K|j |yN)items isinstancelist TypeErrortypeupdate)leftrightresultklvlkrvrs r merge_familyr3@sm F**,!Bkkm !FBb$'R))bF2J !!  KKrtestcase classnamename)filelineurl)_base _base_legacyr:xunit1r;xunit2ceZdZddZddZddZddZddZddZddZ ddd Z dd Z dd Z dd Z dd ZddZddZddZddZddZddZy) _NodeReporterc||_||_|jj|_|jj|_d|_g|_g|_i|_y)N)idxml add_statsfamilyduration propertiesrattrs)selfnodeidrCs r__init__z_NodeReporter.__init__WsL++hhoo  13') %' rc|jj|j|jj |yr%)rCrDtagrappend)rInodes rrNz_NodeReporter.appendas* 488$ $rcb|jjt|t|fyr%)rGrNrr#rIr6values r add_propertyz_NodeReporter.add_propertyes" D >%+@ABrcFt||jt|<yr%)r#rHrrQs r add_attributez_NodeReporter.add_attributehs .u 5 3t9rc|jrRtjd}|jD],\}}|jtjd||.|Syz9Return a Junit node containing custom properties, if any.rGpropertyr6rRN)rGETElementrNrIrGr6rRs rmake_properties_nodez"_NodeReporter.make_properties_nodeksT ??L1J# R e!!"**Zd%"PQ R rct|j}|j}|dd}|jjr&|j d|jjdj |t|d|jdd}|jdt|jd|d<t|dr|j|d<||_|jj||jdk(ryi}|jD]-}|t|jd vs|j|||</||_y) Nr.)r5r6r7r8r9r<r4)mangle_test_addressrJrHrCprefixinsertjoinr#locationrhasattrr9r+rEfamilies)rI testreportnamesexisting_attrs classnamesrH temp_attrskeys rrecord_testreportz_NodeReporter.record_testreportts-#J$5$563BZ 88??   a 1*-"59-''*!    q ! - 3 3A 67E&M :u %%>>E%L  .) ;;( "  :: 2Cht{{+J77"&**S/ 3 2  rctjd|j|jd}|j }||j ||j |j|S)Nr4.3f)time)rZr[rHrFr]rNextendr)rIr4rGs rto_xmlz_NodeReporter.to_xmlsV::j$**dmmC=PR..0  ! OOJ ' #rNcttj||}t||_|j |y)N)messagerZr[r#textrN)rIrMrvdatarOs r _add_simplez_NodeReporter._add_simples*zz#w/"4(  DrcR|jjs |jry|j}|j}|j }|jj dk(ryd}|jj dvr|j|d}|jj dvr*||j|dz }|j||dd}|jj dvr*||j|d z }|j||d d}|r|j||dyy) Nno)logallz Captured Log ) system-outout-errrz Captured Out r) system-errrrz Captured Err r) rClog_passing_testspassed capstdoutcaplog capstderrlogging_prepare_content_write_content)rIreport content_out content_log content_err content_alls rwrite_captured_outputz#_NodeReporter.write_captured_outputsxx))fmm && mm && 88  t #  88  ~ -// =MNK 88  ? ? 400>NO OK    \ BK 88  ? ? 400>NO OK    \ BK     \ B rcJdj|jdd|dgS)N P-r})recenter)rIcontentheaders rrz_NodeReporter._prepare_contents#yy&--C0'2>??rcptj|}t||_|j |yr%rw)rIrrjheaderrMs rrz_NodeReporter._write_contents(jj!!'* Crc&|jdy)Nr)rDrIrs r append_passz_NodeReporter.append_passs x rc6t|dr|jddy|jJt|jdd}| |j}nt |j}t |}|jd|t |jy)Nwasxfailskippedz%xfail-marked test passes unexpectedly reprcrashfailure)rgrzlongreprgetattrrvrr#)rIrrrvs rappend_failurez_NodeReporter.append_failures 6: &   Y(O P??. ..18d2I$#++foo.$W-G   YV__1E Frcl|jJ|jddt|jy)Nerrorzcollection failure)rrzrrs rappend_collect_errorz"_NodeReporter.append_collect_errors.*** "6FOO8LMrcP|jddt|jy)Nrzcollection skipped)rzrrrs rappend_collect_skippedz$_NodeReporter.append_collect_skippeds $8#foo:NOrc,|jJt|jdd}| |j}nt|j}|jdk(rd|d}nd|d}|j dt |t|jy)Nrteardownzfailed on teardown with ""zfailed on setup with "r)rrrvrwhenrzr#)rIrrreasonmsgs r append_errorz_NodeReporter.append_errors***-4V__kSW-X  &&F)F ;;* $-fXQ7C*6(!4C ."5s6??7KLrct|drW|j}|jdr|dd}t|}t j dd|}|j |yt|jtsJ|j\}}}|jdr|dd}|d |d |}t j dd t|}t||_ |j ||j|y) Nrzreason: rz pytest.xfail)r*rvz Skipped: :z: z pytest.skip) rgr startswithr#rZr[rNr'rtuplerxr)rIr xfailreasonrfilenamelineno skipreasondetailss rappend_skippedz_NodeReporter.append_skippeds 6: & //K%%j1)!"o (5KjjUG KK foou5 55+1?? (Hfj$$[1'^ ! !F82j\:Gjj ~j7QG*'2GL KK  & &v .rcn|j|jjfd|_y)NcSr%)rysrz(_NodeReporter.finalize..sdr)rt__dict__clear)rIrys @rfinalizez_NodeReporter.finalizes'{{} # r)rJzstr | TestReportrCrrNone)rO ET.Elementrrr6rrRobjectrrrzET.Element | None)rir rr)rrr%)rMrrvrry str | Nonerrrr rr)rrrrrr)rr rrrrrrrr)__name__ __module__ __qualname__rKrNrSrUr]rortrzrrrrrrrrrrrrrr?r?Vsc( C6 < C.@ !G N P M/,#rr?cddlm}|jjj t d}|A|j dvr2|jj||d|j dyyy)z[Emit a PytestWarning about the given fixture being incompatible with newer xunit revisions.r) PytestWarningN)r<legacyz$ is incompatible with junit_family 'z' (use 'legacy' or 'xunit1')) _pytest.warning_typesrconfigstashgetxml_keyrErOwarn)request fixture_namerrCs r!_warn_incompatibility_with_xunit2rsl4 ..   " "7D 1C 3::-AA  . DSZZLPlm  Brc,tddfd }|S)anAdd extra properties to the calling test. User properties become part of the test report and are available to the configured reporters, like JUnit XML. The fixture is callable with ``name, value``. The value is automatically XML-encoded. Example:: def test_function(record_property): record_property("example_key", 1) record_propertycTjjj||fyr%)rOuser_propertiesrN)r6rRrs rappend_propertyz(record_property..append_property%s $$++T5M:rr)r)rrs` rrrs&g/@A; rc2ddlm}|jj|dt |ddd}|}|j j jtd}|1|j|jj}|j}|S)zAdd extra xml attributes to the tag for the calling test. The fixture is callable with ``name, value``. The value is automatically XML-encoded. r)PytestExperimentalApiWarningz/record_xml_attribute is an experimental featurerecord_xml_attributecyr%rrYs r add_attr_noopz+record_xml_attribute..add_attr_noop;s rNr) rrrOrrrrrr node_reporterrJrU)rrr attr_funcrCrs rrr+sC LL$%VW&g/EF I ..   " "7D 1C ))',,*=*=> !// rcd}t|ts1d}t|j|t |j y)zcUsed by record_testsuite_property to check that the given parameter name is of the proper type.Tz5{param} parameter needs to be a string, but {g} given)paramgN)r'rr)formatr*r)rv__tracebackhide__rs r_check_record_param_typerHs@ a E $q'2B2B CDD rsession)scopecd}dd}|jjjtd}| |j}|S)a+Record a new ```` tag as child of the root ````. This is suitable to writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family. This is a ``session``-scoped fixture which is called with ``(name, value)``. Example: .. code-block:: python def test_foo(record_testsuite_property): record_testsuite_property("ARCH", "PPC") record_testsuite_property("STORAGE_TYPE", "CEPH") :param name: The property name. :param value: The property value. Will be converted to a string. .. warning:: Currently this fixture **does not work** with the `pytest-xdist `__ plugin. See :issue:`7767` for details. Tc d}td|y)zFNo-op function in case --junit-xml was not passed in the command-line.Tr6N)r)r6rRrs r record_funcz.record_testsuite_property..record_funcms  .rNr)rrrradd_global_property)rrrrCs rrecord_testsuite_propertyrQsC4/ ..   " "7D 1C -- rc |jd}|jdddddtjtddd |jd d dd dd |j ddd|j ddd|j dddd|j ddd|j ddd y)!Nzterminal reportingz --junitxmlz --junit-xmlstorexmlpathpath)optnamez0Create junit-xml style report file at given path)actiondestmetavarr*defaulthelpz --junitprefixz--junit-prefixrz0Prepend prefix to classnames in junit-xml output)rrrrjunit_suite_namez Test suite name for JUnit reportpytest)r junit_loggingz\Write captured log messages to JUnit report: one of no|log|system-out|system-err|out-err|allr|junit_log_passing_testsz;Capture log information for passing tests to JUnit report: boolT)r*rjunit_duration_reportz*Duration time to report: one of total|calltotal junit_familyz0Emit XML for schema: one of legacy|xunit1|xunit2r=)getgroup addoption functoolspartialr addini)parserrs rpytest_addoptionr xs OO0 1E OO    |\ B ?  OO ?  MM> MM :   MM!E    MM4  MM:rc |jj}|rt|ds|jd}t ||jj |jd|jd|jd||jd|j t<|jj|j tyyy)N workerinputrrrrr) optionrrggetinir junitprefixrr pluginmanagerregister)rrrs rpytest_configurersmm##Gwv}5}}^4 &  MM % % MM, - MM/ * MM1 2  MM3 4!  W %%fll7&;<6wrc|jjtd}|r-|jt=|jj |yyr%)rrrr unregister)rrCs rpytest_unconfigurers@ ,,  7D )C LL !'', rc|jd\}}}|jd}|djtjd|d<t j dd|d|d<|dxx||zz cc<|S)N[z::rr`z\.py$r}r_) partitionsplitreplacerSEPrr )addressrpossible_open_bracketparamsrjs rrbrbsy*1*;*;C*@'D  JJt EQx 3/E!HvvhE!H-E!H "I&//I LrceZdZ d ddZddZddZddZddZddZddZ ddZ dd Z dd Z dd Z dd Zdd ZddZy)rctjjtjj|}tjj tjj ||_||_||_||_ ||_ ||_ ||_ tjgdd|_i|_g|_g|_g|_d|_|jdk(rd|_ yy)N)rrrrrrr<)osr expanduser expandvarsnormpathabspathlogfilerc suite_namerrreport_durationrEdictfromkeysstatsnode_reportersnode_reporters_orderedglobal_properties open_reportscnt_double_fail_tests)rIr)rcr*rr+rErs rrKzLogXML.__init__s''$$RWW%7%7%@Aww''(@A  $ !2. %)]] 5q&  UW;=#8:/1%&" ;;( ""DK #rct|d|}t|dd}|jj||f}|jD] \}}|j |t |"||j yyNrJrO)rr/poprrSrr)rIrrJ workernodereporterpropname propvalues rrzLogXML.finalizes62VVT2 &&**FJ+?@#)#9#9 < Hi  ! !(C N ; <       rct|d|}t|dd}||f}||jvr|j|St||}||j|<|jj ||Sr5)rr/r?r0rN)rIrrJr7rnr8s rrzLogXML.node_reporters|#*68V#DVVT2 j  $%% %&&s+ + .#+C  ##**84rcP||jvr|j|xxdz cc<yy)Nra)r.)rIrns rrDzLogXML.add_stats s% $**  JJsOq O rcJ|j|}|j||Sr%)rrorIrr8s r _opentestcasezLogXML._opentestcases%%%f-""6*rc8d}jr4jdk(rL|j}|jn(jrjdk(rct ddt ddt fd|jDd}|r&|j||xjdz c_ |j}jdk(rJ|j|jj|jsR|jn@|jn.jr"|j}|j!|j#jdk(r|j}|j|jt ddt ddt fd|jDd}|r|jj%|yyy) aHandle a setup/call/teardown report, generating the appropriate XML tags as necessary. Note: due to plugins like xdist, this hook may be called in interlaced order with reports from other nodes. For example: Usual call order: -> setup node1 -> call node1 -> teardown node1 -> setup node2 -> call node2 -> teardown node2 Possible call order in xdist: -> setup node1 -> call node1 -> setup node2 -> call node2 -> teardown node2 -> teardown node1 Ncallr worker_id item_indexc3K|]?}|jjk(r$t|ddk(rt|ddk(r|AywrCNrBrJr.0repr report_ii report_wids r z2LogXML.pytest_runtest_logreport..5sKJJ&--7 '\4 @I M '[$ ?: M AArac3K|]?}|jjk(r$t|ddk(rt|ddk(r|AywrErFrGs rrLz2LogXML.pytest_runtest_logreport..ZsK fmm3#Ct< I#Cd;zI rM)rrr?rfailedrnextr2rr3rrNrrrrrupdate_testcase_durationremove)rIr close_reportr8rJrKs ` @@rpytest_runtest_logreportzLogXML.pytest_runtest_logreports. =={{f$--f5$$V, ]]{{j($V[$? #FL$? ##'#4#4   MM,/..!3.))&1H{{f$''/!!((0--226:%%f- ^^))&1H  # #F + %%f- ;;* $))&1H  * *6 2 MM& ! d;J d;I#00 L!!((6' %rc|jd|jhvr2|j|}|xjt |ddz c_yy)zAccumulate total duration for nodeid from given report and update the Junit.testcase with the new total if already created.rrFrAN)r+rrrFrr>s rrQzLogXML.update_testcase_durationhsJ   GV[[#9 9))&1H   S!A A  :rc|jsA|j|}|jr|j|y|j |yyr%)rr?rOrrr>s rpytest_collectreportzLogXML.pytest_collectreportosA}}))&1H}}--f5//7 rc|jd}|jjdd|jddt |y)Ninternalr)r5r6rzinternal error)rrHr+rzr)rIexcreprr8s rpytest_internalerrorzLogXML.pytest_internalerrorws@%%j1zBW&6G Erc6tj|_yr%)rInstant suite_start)rIs rpytest_sessionstartzLogXML.pytest_sessionstart|s!>>+rc tjjtjj|j}tj |dt |jdd5}|jj}|jd|jdz|jdz|jd z|jz }|jd tjd |jt|jd t|jdt|jdt||j d |jj#j%j't)j* }|j-}||j/||j0D]!}|j/|j3#tjd}|j5dd|j/||jtj6|ddddy#1swYyxYw)NT)exist_okwzutf-8)encodingrrrrz& testsuiterq)r6errorsfailuresrtestsrr timestamphostname testsuitesr6z pytest testsunicode)r$rdirnamer(r)makedirsopenr^elapsedr.r3writerZr[r*rsecondsas_utc astimezone isoformatplatformrO_get_global_properties_noderNr0rtsettostring) rIrlr)rFnumtests suite_noder1rrjs rpytest_sessionfinishzLogXML.pytest_sessionfinishs''//"''//$,,"?@ Gd+ $,,g 6 G'''//1H 8$**Y'(**Y'(**W%&,, -  MMB C__4::g./TZZ 23DJJy12(m ((-**113>>@JJL! J!% @ @ B  ,!!"34!%! 2   j ) MM"++j9E F? G G Gs 6G.I--I6cj|jdk\r |jdd|jyy)Nrrzgenerated xml file: ) get_verbosity write_sepr))rIterminalreporterrs rpytest_terminal_summaryzLogXML.pytest_terminal_summarys6    !Q &  & &s.B4<<.,Q R 'rcld}td||jj|t|fy)NTr6)rr1rNr#)rIr6rRrs rrzLogXML.add_global_propertys0  . %%t^E-B&CDrc|jrRtjd}|jD],\}}|jtjd||.|SyrW)r1rZr[rNr\s rrvz"LogXML._get_global_properties_nodesX  ! !L1J#55 R e!!"**Zd%"PQ R rN)rr|rr<T) rcrr*rrrr+rrrrrr)rzTestReport | strrr?)rnrrr)rr rr?)rZrrrr)rrrz pytest.Configrrrr)rrrrKrrrDr?rTrQrWr[r_r{rrrvrrrrrs #&"&## #  #  # # #B  $! S7jB8F ,$GLS 0S:GS S E r)r!rrrr)rr rrrr)rr rzCallable[[str, object], None])rrrrrr)r r rr)rr rr)rrrz list[str])2__doc__ __future__rcollections.abcrr r$rurxml.etree.ElementTreeetree ElementTreerZ_pytestrr_pytest._code.coderr_pytest.configr r _pytest.config.argparsingr _pytest.fixturesr _pytest.reportsr _pytest.stashr_pytest.terminalrrrr#r3rhcopyr?rfixturerrrrr rrrbrrrrrsb#$  "",/!',+&"-  (8  26;/ 0!89  g&++- Xh .!9:g&l#l#^    +.     ,8Ei #!#L,^="-mmr