
    !hig                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	 ej                         j                   ej                                	 d dlZd dlZd dlmZ d dlmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d	Z h d
Z!ejD                  jG                  dd      dk(  Z$d Z% ejL                  dd      d        Z'd Z(d Z)d Z*d Z+d Z,d Z-ej\                  d        Z/ej\                  d        Z0ej\                  d        Z1 G d d      Z2 ej\                  d      d        Z3 ej\                  dd g!      d"        Z4ej\                  d#        Z5ej\                  d$e2fd%       Z6y# e$ r dZY ,w xY w)&    N)__main__)	configure)	is_cygwin	is_darwinis_win)initialize_modgraph)pkg_archive_contents)gen_sourcefile)winutils   >   linuxwin32darwinPYI_BUILDER_CLEANUP1c                     t         j                  d | j                         D              }t        j                  }|r||vrt        j                  d|        yyy)aE  
    Markers to skip tests based on the current platform.
    https://pytest.org/en/stable/example/markers.html#marking-platform-specific-tests-with-pytest

    Available markers: see pytest.ini markers
        - @pytest.mark.darwin (macOS)
        - @pytest.mark.linux (GNU/Linux)
        - @pytest.mark.win32 (Windows)
    c              3   4   K   | ]  }|j                     y wN)name).0marks     FC:\des-py\Monitor\venv\Lib\site-packages\PyInstaller/utils/conftest.py	<genexpr>z'pytest_runtest_setup.<locals>.<genexpr>B   s     5`Ddii5`s   zdoes not run on N)SUPPORTED_OSESintersectioniter_markerssysplatformpytestskip)itemsupported_platformsplats      r   pytest_runtest_setupr$   8   sT     )555`DL]L]L_5``<<Dt+>>&tf-.  ?    T)tryfirsthookwrapperc              #   h   K   d }|j                         }t        | d|j                   |       y w)Nrep_)
get_resultsetattrwhen)r!   calloutcomereps       r   pytest_runtest_makereportr0   H   s4      G



C DD
#S)s   02c                 J    | j                   j                         j                  S r   )pathresolveparentrequests    r   _get_base_dirr7   S   s    <<!(((r%   c                     t        |       dz  S )Nscriptsr7   r5   s    r   _get_script_dirr;   X       !I--r%   c                     t        |       dz  S )Nmodulesr:   r5   s    r   _get_modules_dirr?   ]   r<   r%   c                     t        |       dz  S )Nlogsr:   r5   s    r   _get_logs_dirrB   b       !F**r%   c                     t        |       dz  S )Ndatar:   r5   s    r   _get_data_dirrF   g   rC   r%   c                     t        |       dz  S )Nspecsr:   r5   s    r   _get_spec_dirrI   l   s    !G++r%   c                     t        |       S )z@
    Return the directory where the test spec-files reside.
    )rI   r5   s    r   spec_dirrK   p   s    
 !!r%   c                     t        |       S )z=
    Return the directory where the test scripts reside.
    )r;   r5   s    r   
script_dirrM   x   s    
 7##r%   c                     | j                   j                  dd  }t        |       |z  }|dz  }t        j                  ||       |S )N   rE   )function__name__rF   shutilcopytree)r6   tmp_path	test_namesource_data_dirtmp_data_dirs        r   data_dirrX      sK       ))!"-I $G,y8Of$L
OOO\2r%   c                   R    e Zd Zd Zd Zd Zd Z	 ddZd Zd Z	d	 Z
d
 Zd Zd Zy)
AppBuilderc                 r    || _         || _        || _        || _        |dz  | _        |dz  | _        d| _        y )NdistbuildF)	_tmp_path_request_mode	_spec_dir	_dist_dir
_build_dir_is_spec)selfrT   r6   bundle_modes       r   __init__zAppBuilder.__init__   s=    ! 
!!F*"W,r%   c                 p    d}t        | j                        |z  }d| _         | j                  |g|i |S )zU
        Test a Python script that is referenced in the supplied .spec file.
        T)rI   r_   rd   test_script)re   specfileargskwargs__tracebackhide__s        r   	test_speczAppBuilder.test_spec   sA     ! /(:t:4:6::r%   c                     d}t        | j                  ||j                  d            }|d=  | j                  |g|i |S )a
  
        Test a Python script given as source code.

        The source will be written into a file named like the test-function. This file will then be passed to
        `test_script`. If you need other related file, e.g., as `.toc`-file for testing the content, put it at at the
        normal place. Just mind to take the basnename from the test-function's name.

        :param script: Source code to create executable from. This will be saved into a temporary file which is then
                       passed on to `test_script`.

        :param test_id: Test-id for parametrized tests. If given, it will be appended to the script filename, separated
                        by two underscores.

        All other arguments are passed straight on to `test_script`.
        Ttest_id)r
   r^   
setdefaultri   )re   sourcerk   rl   rm   
scriptfiles         r   test_sourcezAppBuilder.test_source   sL      !#DNNFF<M<Mi<XY
9t
<T<V<<r%   c                     t        d| d| t        j                         t        d| d| t        j                         y )Nz[APP-BUILDER:z] )file)printr   stdoutstderr)re   	step_namemessages      r   _display_messagezAppBuilder._display_message   s:     	i[7)43::Fi[7)43::Fr%   Nc                    d}|rt         t        j                  d       |g }|g }|r | j                  sS|j	                  d|g       n?t
        j                  j                  t
        j                  j                  |            d   }t
        j                  j                  |      st        | j                        |z  }t        |      | _        t
        j                  j                  | j                        sJ d| j                  d       | j                  dd	       | j!                  |
      st        j"                  d| d       | j                  dd        | j$                  |f|||d| | j                  dd       y)a0  
        Main method to wrap all phases of testing a Python script.

        :param script: Name of script to create executable from.
        :param pyi_args: Additional arguments to pass to PyInstaller when creating executable.
        :param app_name: Name of the executable. This is equivalent to argument --name=APPNAME.
        :param app_args: Additional arguments to pass to
        :param runtime: Time in seconds how long to keep executable running.
        :param toc_log: List of modules that are expected to be bundled with the executable.
        TNz4Interactive tests require psutil for proper cleanup.z--namer   zScript z not found.zTEST-SCRIPTzStarting build...)rk   zBuilding of  failed.z)Build finished, now running executable...)rk   runtimerun_from_pathzRunning executable finished.)psutilr   r    rd   extendosr2   splitextbasenameisabsr;   r_   strscriptexistsr|   _test_buildingfail_test_executables)	re   r   pyi_argsapp_nameapp_argsr   r   rl   rm   s	            r   ri   zAppBuilder.test_script   sP    ! v~KKNOHH==8 45 ww''(8(8(@A!DH ww}}V$$T]]3f<F&kww~~dkk*Pgdkk_K,PP*m-@A"""1KK,vhh78m-XYxohWdohnom-KLr%   c                    d}| j                  |      }|g k7  sJ d       |D ]  }t        j                  j                  t        j                  j	                  |            d   dz   }	t        | j                        |	z  }	|	j                         r+| j                  ||	      st        j                  d| d       | j                  ||||      }
|
|j                  dd      k7  st        j                  d| d	|
 d
        y)a`  
        Run created executable to make sure it works.

        Multipackage-tests generate more than one exe-file and all of them have to be run.

        :param args: CLI options to pass to the created executable.
        :param runtime: Time in seconds how long to keep the executable running.

        :return: Exit code of the executable.
        TzNo executable file was found.r   z.toczMatching .toc of r~   retcodezRunning exe z failed with return-code .N)_find_executablesr   r2   r   r   rB   r_   r   _examine_executabler   r   _run_executableget)re   r   rk   r   r   rl   rm   exesexetoc_logr   s              r   r   zAppBuilder._test_executables   s     !%%d+rz:::z 		UCgg&&rww'7'7'<=a@6IG#DMM2W<G~~//W=KK"3C5 AB**3mWMG&**Y22l3%/H	QRST		Ur%   c                    g }t        | j                  |z  |z        }t        | j                  |z        }|||dz   |dz   g}t        r|D cg c]  }|dz   	 }}t        r5t        | j                  | dz  dz  dz  |z        }|j	                  |       |D ]M  }t        j
                  |      D ]3  }	t        j                  j                  |	      s#|j	                  |	       5 O |S c c}w )ac  
        Search for all executables generated by the testcase.

        If the test-case is called e.g. 'test_multipackage1', this is searching for each of 'test_multipackage1.exe'
        and 'multipackage1_?.exe' in both one-file- and one-dir-mode.

        :param name: Name of the executable to look for.

        :return: List of executables
        z_?z.exez.appContentsMacOS)	r   rb   r   r   appendglobr   r2   isfile)
re   r   r   	onedir_pt
onefile_ptpatternsptapp_bundle_ptpatternprogs
             r   r   zAppBuilder._find_executables  s     -45	$./

 .67V7H7D6 > Kg UX\ \]MOOM* 	&G		'* &77>>$'KK%&	&  8s   C)c                    t        j                  t        j                        }d|d<   |d= t        r4t        j
                  j                  t        j                               |d<   t        r$t        j
                  j                  ddg      |d<   t        r$t        j
                  j                  g d      |d<   |}|rt        | j                        }t        j                  j                  |      }t        j
                  j                  |j                  dd      t        j                  j!                  |      g      |d<   njt        j                  j!                  |      }t        j                  j                  t        j"                  t        j                  j                  |            }|g|z   }| j%                  |||||      S )z}
        Run executable created by PyInstaller.

        :param args: CLI options to pass to the created executable.
         PATHz/usr/local/bin/usr/bin)r   z/binz	/usr/sbinz/sbin)copydeepcopyr   environr   pathsepjoinr   get_system_pathr   r   r   r^   r2   r   r   dirnamecurdir_run_executable_)	re   r   rk   r   r   prog_envexe_pathprog_cwd	prog_names	            r   r   zAppBuilder._run_executable6  sM    ==,V!zzx/G/G/IJHV!zz0@*/MNHV   "zz/YZHV 4>>*H((.I!zzVR0H"''//Z^J_/`aHV wwt,HRYY0@0@0FGI{T! $$T8XxQQr%   c           	         t         t        j                  nt         j                  }| j                  dd|d|       t	        j                         } |||||      }d x}	}
	 |r|nt
        }|j                  |      \  }	}
t	        j                         |z
  }|j                  }| j                  dd|dd| d	       | j                  dd|        |S # t         t        j                  nt         j                  t        j                  f$ r |r| j                  dd
| d       d}n| j                  dd d       d}t         	 | j                  dd       |j                          |j                  d      \  }	}
| j                  dd       n[# t        j                  $ rz 	 | j                  dd       |j                          |j                  d      \  }	}
| j                  dd       n+# t        j                  $ r | j                  dd       Y nw xY wY nw xY w| j                  dd       t        |j                  d            D ]j  }t        j                  t         j                        5  | j                  dd|j                    d       |j                          d d d        `# 1 sw Y   ixY w 	 | j                  dd|j                    d       |j                  d      \  }	}
| j                  dd       n# t         j                  t        j                  f$ r | j                  dd       t        j                  t         j                        5  |j                          d d d        n# 1 sw Y   nxY w	 |j                  d      \  }	}
| j                  dd       n;# t         j                  t        j"                  f$ r | j                  dd       Y nw xY wY nw xY wY 4w xY w)NzRUN-EXEzRunning z, args: )
executableenvcwd)timeoutz Process exited on its own after z.1fz seconds with return code r   z%Process reached expected run-time of z	 seconds.r   z+Timeout while running executable (timeout: z
 seconds)!   z/Stopping the process using Popen.terminate()...rO   zProcess stopped.z*Stopping the process using Popen.kill()...z6Failed to stop the process (or its child process(es))!zStopping child processes...T)	recursivezStopping child process z...zWaiting for main process (z) to stop...zProcess stopped on its own.zDone! Return code: )r   
subprocessPopenr|   time_EXE_TIMEOUTcommunicate
returncodeTimeoutExpired	terminatekilllistchildren
contextlibsuppressNoSuchProcesspidTimeoutExpire)re   rk   r   r   r   r   popen_implementation
start_timeprocessrx   ry   r   elapsedr   child_processs                  r   r   zAppBuilder._run_executable_a  s   39>z//v|| 	i8H<xx)PQYY[
&thT\] F	s!(glG$000ANFFiikJ.G((G!!=gc]JdeldmmnoF 	i+>wi)HIE /5n
))6CXCXZdZsZsBt >	s %%i3XY`Xaaj1kl %%i3^_f^ggq1rs~s)))5fg%%'%,%8%8%8%CNFF)))5GH!00 s	s--i9ef *1)<)<Q)<)G--i9KL%44 s--i9qrss  %%i1NO%)'*:*:T*:*J%K -M#,,V-A-AB ---i;RS`SdSdReeh9ij%**,- - --s)))7QRYR]R]Q^^j5kl%,%8%8%8%CNFF)))5RS--z/H/HI 
s)))5ab#,,V-A-AB '' ' 's)0)<)<Q)<)G--i9KL"11:3K3KL s--i9qrs
si>	ss   $AC A3O5A	FO5H#*A	G43H#4%HH#HH#O5"H##AO591J3*	O53J<8O5AL	O5	AO.!M;2	O.;N O.'N0/O.05O(%O.'O((O.+O5-O..O54O5c                 t   | j                   r/dt        | j                        dt        | j                        ddg}ndddt        | j                        dt        | j                        dt        | j                        dt        t        | j                              ddg}| j                  d	k(  r|j                  d
       n | j                  dk(  r|j                  d       | j                  g||}t        j                         }t        | j                        |d<   t        j                  ||       d}|dk(  S )z
        Run building of test script.

        :param args: additional CLI options for PyInstaller.

        Return True if build succeeded False otherwise.
        z
--distpathz
--workpathz--log-levelINFOz--debug=bootloaderz--noupxz
--specpathz--pathonedirz--onedironefilez	--onefilecachedirr   )rd   r   rb   rc   ra   r?   r_   r`   r   r   r   
get_configr^   pyi_mainrun)re   rk   default_argsr   
PYI_CONFIGr   s         r   r   zAppBuilder._test_building  s    ==c$..1c$//2vL %c$..1c$..1c$//2#.t}}=>vL zzX%##J/y(##K0 KK6,66))+
!$T^^!4
:Xz*!|r%   c           	         | j                  ddt        |             t        |      }t        |dd      5 }t	        |j                               }ddd       j                          g }|D ]_  }|D ]2  }t        j                  ||      s| j                  dd|d|        9 |j                  |       | j                  dd	|       a | S # 1 sw Y   xY w)
z{
        Compare log files (now used mostly by multipackage test_name).

        :return: True if .toc files match
        zEXAMINE-EXEzMatching against TOC log: rzutf-8)encodingNzEntry found: z --> zEntry MISSING: )
r|   r   r	   openevalreadsortrematchr   )	re   r   r   
fname_listfpattern_listmissingr   fnames	            r   r   zAppBuilder._examine_executable  s     	m/I#g,IY-Z[)#.
'31 	*Q>L	* 	# 	TG# T88GU+))-=SXY^Xa9bcT w'%%mwk5RS	T {!	* 	*s   CC)NNNNF)rQ   
__module____qualname__rg   rn   rt   r|   ri   r   r   r   r   r   r    r%   r   rZ   rZ      sJ    ;=,G `e,M\U4#J)RVXt)Vr%   rZ   session)scopec                  n    dd l m}  | j                  j                  | j                         t                y )Nr   )PyInstaller.loglogloggersetLevelDEBUGr   )loggings    r   pyi_modgraphr     s#     &NNGMM*r%   r   r   )paramsc              #     K   |j                  dt        j                  d          |j                  d        |j	                  |        |j                  ddg i       t        | ||j                         t        rk|j                  j                  j                  rJ|j                  j                  j                  r)| j                         rt        j                  | d       y y y y y wNr   zPyInstaller.config.CONFpathexT)ignore_errors)setenvr   r   syspath_prependchdirr+   rZ   param_PYI_BUILDER_CLEANUPnode	rep_setuppassedrep_callr   rR   rmtree)rT   monkeypatchr6   r   s       r   pyi_builderr	    s      vrzz&12%h 1Hb>B
Xw
66  6 6 = =',,BWBWB^B^??MM($7  C_ =s   C%C'c              #     K   |j                  dt        j                  d          |j                  |        |j	                  d        |j                  ddg i       t        | |d        t        rk|j                  j                  j                  rJ|j                  j                  j                  r)| j                         rt        j                  | d       y y y y y wr   )r   r   r   r   r   r+   rZ   r  r  r  r  r  r   rR   r  )rT   r6   r  r   s       r   pyi_builder_specr  "  s      vrzz&12h% 1Hb>B
Xw
--  6 6 = =',,BWBWB^B^??MM($7  C_ =s   CCr	  c              #   (   K   d }|| _         |  yw)z=A pyi_builder equivalent for testing --windowed applications.c                 N    t        j                  |g| |||      j                  S )N)r   r   r   )r   r   r   )rk   r   r   r   r   s        r   r   z.pyi_windowed_builder.<locals>._run_executable_>  s&    ~~x/$/X8U\]hhhr%   N)r   )r	  r   s     r   pyi_windowed_builderr  6  s     i $4K 
s   )7r   r   r   r   r   r   rR   r   r   r   	getLogger
addHandlerNullHandlerr   ModuleNotFoundErrorr   PyInstallerr   r   r   PyInstaller.compatr   r   r   PyInstaller.depend.analysisr   PyInstaller.archive.readersr	   PyInstaller.utils.testsr
   PyInstaller.utils.win32r   r   r   r   r   r  r$   hookimplr0   r7   r;   r?   rB   rF   rI   fixturerK   rM   rX   rZ   r   r	  r  r  r   r%   r   <module>r     s       	 	   
 
      2w224 5  , ! ; ; ; < 2 , -zz~~&;SASH /  $D1* 2*)
.
.
+
+
, " " $ $  ,e eT i  ! ),-8 .8( 8 8& j  o  Fs   E? ?F
	F
