o
    qoi;                     @   s  d 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	ddl
mZ ddlmZ ddlmZ ddlmZmZ ddlmZmZmZmZmZmZmZ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&m'Z' ddl(m)Z) ej*dkrddlm+Z+ nddl,m+Z+ ed_dedee fddZ-G dd dZ.G dd de+Z/G dd dZ0G dd de+Z1d_dee2 ddfddZ3d`dd Z4d!e5 fd"e2d#e6d$e2ddfd%d&Z7d!e5 fd"e2d#e6d$e2de2fd'd(Z8	d_d)e&d*eee2  ddfd+d,Z9d-e2d.ede2ee2 f de2fd/d0Z:dd1dd2d3d4 fd5ed6ed*ee2 d7ee2ee2 f d8ee2ee2 f d9ede2ee2 f d:e2d;eee2e2f  d<e;d=ed>ee2 f de2fd?d@Z<d_dAedBede2fdCdDZ=		2	E	EdadAedBedFe;dGe;dHe;dee2e2f fdIdJZ>		E	E	dbdAedBedGe;dHe;dKee? dee2e2f fdLdMZ@dNe2de2fdOdPZA	RdcdSe2dTe2dUe2dVe2ddf
dWdXZB	RdcdSe2dTe2dUe2dVe2ddf
dYdZZC	Rdcd[e2d\e2dUe2dVe2ddf
d]d^ZDdS )dz
Utilities used by tests
    N)contextmanager)unified_diff)Path)PIPEPopen)AnyCallableDictIteratorListOptionalTupleUnion)	Container
DictConfig	OmegaConf)Hydra)detect_task_name)GlobalHydra)	JobReturnvalidate_config_path)TaskFunction)      r   )Protocolenter_resultreturnc                 c   s    | V  d S N )r   r   r   O/home/ubuntu/.local/lib/python3.10/site-packages/hydra/test_utils/test_utils.pydoes_not_raise"   s   
r    c                   @   P   e Zd ZdZdddZdedefddZdd	d
ZdedededdfddZ	dS )TaskTestFunction
    Context function
    r   Nc                 C   s:   d | _ d | _d | _d | _d | _d | _d | _d | _d| _d S NF)	temp_dir	overridescalling_filecalling_moduleconfig_pathconfig_namehydrajob_retconfigure_loggingselfr   r   r   __init__,   s   
zTaskTestFunction.__init__cfgc                 C   s   dS )9
        Actual function being executed by Hydra
        d   r   r/   r1   r   r   r   __call__7   s   zTaskTestFunction.__call__c                 C   s   zHt | j t| j| j}tj| j| j| j|d| _t	 | _
t| j}|d us+J |d| j
  | jj| j| || jd| _| W t   S t   w )Nr'   r(   r)   job_namezhydra.run.dir=r*   task_functionr&   with_log_configuration)r   r)   r   r'   r(   r    create_main_hydra_file_or_moduler+   tempfilemkdtempr%   copydeepcopyr&   appendrunr*   r-   r,   r   clear)r/   r7   r&   r   r   r   	__enter__>   s*   

zTaskTestFunction.__enter__exc_typeexc_valexc_tbc                 C   0   | j rt  | jd usJ tj| jdd d S NT)ignore_errorsr-   loggingshutdownr%   shutilrmtreer/   rD   rE   rF   r   r   r   __exit__X   s   zTaskTestFunction.__exit__r   N)r   r"   
__name__
__module____qualname____doc__r0   r   r   r5   rC   rP   r   r   r   r   r"   '   s    

r"   c                   @   sP   e Zd Z		ddee dee dee dee deee  ded	efd
dZdS )TTaskRunnerNFr'   r(   r)   r*   r&   r-   r   c                 C      d S r   r   )r/   r'   r(   r)   r*   r&   r-   r   r   r   r5   a   s   	zTTaskRunner.__call__r$   )	rS   rT   rU   r   strr   boolr"   r5   r   r   r   r   rW   `   s$    
rW   c                   @   r!   )SweepTaskFunctionr#   r   Nc                 C   s@   d| _ d| _d| _d| _d| _d| _d| _d| _d| _d| _	dS )zq
        if sweep_dir is None,  we use a temp dir, else we will create dir with the path from sweep_dir.
        NF)
r%   r&   r'   r(   r9   r)   r*   sweepsreturnsr-   r.   r   r   r   r0   r   s   
zSweepTaskFunction.__init__r1   c                 C   s   | j dur
|  |S dS )r2   Nr3   )r9   r4   r   r   r   r5      s   

zSweepTaskFunction.__call__c                 C   s   t | j}|d usJ | jrt| jjddd nt | _|d| j  z,t	| j
 t| j| j}tj| j| j| j
|d}|j| j| || jd| _W t   | S t   w )NTparentsexist_okzhydra.sweep.dir=r6   r8   )r>   r?   r&   r%   r   mkdirr<   r=   r@   r   r)   r   r'   r(   r   r;   multirunr*   r-   r]   r   rB   )r/   r&   r7   hydra_r   r   r   rC      s0   



zSweepTaskFunction.__enter__rD   rE   rF   c                 C   rG   rH   rJ   rO   r   r   r   rP      s   zSweepTaskFunction.__exit__rQ   )r   r[   rR   r   r   r   r   r[   m   s    

r[   c                   @   sl   e Zd ZU eee  ed< 	ddee dee dee dee dee deee  d	ee	 d
e
fddZdS )TSweepRunnerr]   Nr'   r(   r9   r)   r*   r&   r%   r   c                 C   rX   r   r   )r/   r'   r(   r9   r)   r*   r&   r%   r   r   r   r5      s   
zTSweepRunner.__call__r   )rS   rT   rU   r   r   __annotations__r   rY   r   r   r[   r5   r   r   r   r   rd      s(   
 

	rd   subdirc                 C   s$   t dd | durt|  dS dS )z
    Change the cwd to the root of the hydra project.
    used from unit tests to make them runnable from anywhere in the tree.
    ATTRIBUTIONtargetN)_chdir_to_dir_containingoschdir)rf   r   r   r   chdir_hydra_root   s   
rm   c                   C   s   t dd dS )zI
    Change the cwd to the root of the plugin (location of setup.py)
    zsetup.pyrh   N)rj   r   r   r   r   chdir_plugin_root   s   rn      ri   max_upinitial_dirc                 C   s   t | ||}t| d S r   )find_parent_dir_containingrk   rl   ri   rp   rq   curr   r   r   rj      s   rj   c                 C   s   |}t jt j|| s/|dkr/t jt j|d}|d }t jt j|| s/|dks|dkr?td|  dt   |S )Nr   z..   zCould not find z in parents of )rk   pathexistsjoinrelpathIOErrorgetcwdrs   r   r   r   rr      s   rr   
job_returnr&   c                 C   s   t | tsJ | jdusJ | jdusJ | jdusJ tjtj| j| jd s-J tj| j| jj	j
}tjtj|dsEJ tjtj|dsRJ ttj|dt|p`g kseJ dS )z2
    Verify that directory output makes sense
    Nz.logconfig.yamlzoverrides.yaml)
isinstancer   working_dir	task_name	hydra_cfgrk   rv   rw   rx   r+   output_subdirr   loadcreate)r|   r&   	hydra_dirr   r   r   verify_dir_outputs   s"   r   indent
statementsc                 C   sP   t |tr|g}d}|d u st|dkrd}|S |D ]}||  | d7 }q|S )N r   pass
)r~   rY   len)r   r   codepr   r   r   _get_statements   s   
r   ztask.pyFc                 O   s   | S r   r   )cmdargskwargsr   r   r   <lambda>  s    r   tmpdirtask_configprintsexpected_outputsprologfilenameenv_overrideclean_environmentgenerate_custom_cmd.c
              	   C   s$  t | jddd t|tr|g}t|tst|}t|tr#|g}dd |D }td}
t	d|d}t	d|d}|d ure| d	 }t
t|d
}|d t|| W d    n1 s`w   Y  t| d }|dd}|
j|||d}| | }|jt|dd tjt|g}t }zztt|  |	||}|| |ri }ntj }|d ur|| tj||d t
|d}| }t|}W d    n1 sw   Y  |d urt|t|ksJ d| d| tt|D ]}t|| ||  q|W t| S t| w )NTr^   c                 S   s   g | ]}d | dqS )zf.write(z + "\n")r   ).0r   r   r   r   
<listcomp>  s    z$integration_test.<locals>.<listcomp>a
  import hydra
import os
from hydra.core.hydra_config import HydraConfig

$PROLOG

@hydra.main(version_base=None, config_path='.', config_name='config')
def experiment(cfg):
    with open("$OUTPUT_FILE", "w") as f:
$PRINTS

if __name__ == "__main__":
    experiment()
z        )r   r   r   r}   wz# @package _global_
z
output.txt\z\\)PRINTSOUTPUT_FILEPROLOGutf-8)encoding)envrz'Unexpected number of output lines from z, output lines:

) r   ra   r~   rY   r   r   r   stringTemplater   openwritesavereplace
substitute
write_textsys
executablerk   r{   rl   extendenvironr>   update
subprocess
check_callread
splitlinesr   rangeassert_regex_match)r   r   r&   r   r   r   r   r   r   r   s
print_codeprolog_codecfg_filefoutput_filer   	task_filer   orig_dirmodified_envfile_stroutputidxr   r   r   integration_test	  sl   









r   r   r   c                 C   st   t jdg|  } t| tt|d!}| \}}|d dd}|jdks(J W d    |S 1 s3w   Y  |S )N-Werror)stdoutstderrr   r   
r   r   )	r   r   r   r   communicatedecoderstripr   
returncode)r   r   r   _stdoutr   errr   r   r   run_with_error`  s   
r   Tallow_warningsprint_errorraise_exceptionc                 C   s.   |r	t jg|  } nt jdg|  } t| |||S )Nr   )r   r   run_process)r   r   r   r   r   r   r   r   run_python_scripti  s   r   timeoutc              
   C   s   zDt j| d|t jt jd}|j|d\}}t|  }t|  }	|jdkr@|r6tj	
d|	 d |r@t j|j| d||	fW S  tyc }
 z|r]d| } tj	
d	|  d
 |
d }
~
ww )NF)r   shellr   r   r   )r   r   zSubprocess error:
r   )r   r    z=== Error executing:
z
===================)r   r   r   r   normalize_newlinesr   r   r   r   r   r   CalledProcessError	Exceptionrx   )r   r   r   r   r   processbstdoutbstderrr   r   er   r   r   r   w  s4   


r   r   c                 C   s   |  dd ddS )zu
    Normalizes new lines such they are comparable across different operating systems
    :param s:
    :return:
    r   r   )r   )r   r   r   r   r     s   r   ExpectedActual	from_lineto_line	from_nameto_namec                 C   sl   t | } t |}dd t|  | ||dD }d|}t|dkr4td t| td J d	d S )
Nc                 S   s   g | ]}|qS r   r   )r   liner   r   r   r     s    z$assert_text_same.<locals>.<listcomp>)abfromfiletofiler   r   z 
------------ DIFF --------------------------------------------Fz)Mismatch between expected and actual text)r   r   r   rx   r   print)r   r   r   r   linesdiffr   r   r   assert_text_same  s"   

r   c                 C   s   dd t | dD }dd t |dD }t|t|kr(t| |||d t||D ]\}}||krEt||du rEt| |||d q-dS )zCheck that the lines of `from_line` (which can be a regex expression)
    matches the corresponding lines of `to_line` string.

    In case the regex match fails, we display the diff as if `from_line` was a regular string.
    c                 S      g | ]}|r|qS r   r   r   xr   r   r   r         z&assert_regex_match.<locals>.<listcomp>r   c                 S   r   r   r   r   r   r   r   r     r   )r   r   r   r   N)r   splitr   r   ziprematch)r   r   r   r   normalized_from_linenormalized_to_lineline1line2r   r   r   r     s&   r   patternr   c                 C   sZ   t | } t |}tj| |tjddu r+td t|  td t| td J ddS )zCheck that `pattern` (which can be a regex expression)
    matches the corresponding lines of `string` string.
    In case the regex match fails, we display the diff as if `pattern` was a regular string.
    )flagsNz
-------- PATTERN: -----------z---------- STRING: ------------r   FzRegex pattern did not match)r   r   search	MULTILINEr   )r   r   r   r   r   r   r   assert_multiline_regex_search  s   r  r   rQ   )NFTT)NTTN)r   r   )ErV   r>   rK   rk   r   rM   r   r   r   r<   
contextlibr   difflibr   pathlibr   r   r   typingr   r   r	   r
   r   r   r   r   	omegaconfr   r   r   hydra._internal.hydrar   hydra._internal.utilsr   hydra.core.global_hydrar   hydra.core.utilsr   r   hydra.typesr   version_infor   typing_extensionsr    r"   rW   r[   rd   rY   rm   rn   r{   intrj   rr   r   r   rZ   r   r   r   floatr   r   r   r   r  r   r   r   r   <module>   sB  (
9B




$	

W



!


