o
    ,wi \                  
   @   sR  d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	m
Z
mZ ddl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mZmZ ed
G dd dZed
G dd dZdede	e de
e deddf
ddZdede	e de
e deddf
ddZ dede	e de
e deddf
ddZ!ed
G dd dZ"dS )z)
Common test functions testing launchers
    N)Path)AnyCallableListOptionalSet)
DictConfig	OmegaConf)markparamraises)TaskFunction)HydraException)TSweepRunnerintegration_testverify_dir_outputshydra_restore_singletonsc                
   @   sZ  e Zd Zdeeegef  fddZdedede	e de
ddf
d	d
Zdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdedede	e de
ddf
ddZdS )LauncherTestSuitereturnc                 C   s   dt dtfdd}|S )N_r   c                 S      dS )Nd    )r   r   r   c/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/hydra/test_utils/launcher_common_tests.py	task_func      z6LauncherTestSuite.get_task_function.<locals>.task_func)r   r   )selfr   r   r   r   get_task_function   s   z#LauncherTestSuite.get_task_functionhydra_sweep_runnerlauncher_name	overridestmpdirNc                 C   "   t |d| g| |  |d d S Nhydra/launcher=r    task_functiontemp_dirsweep_1_jobr   r   r   r   r    r!   r   r   r   test_sweep_1_job      
z"LauncherTestSuite.test_sweep_1_jobc                 C   r"   r#   )sweep_2_jobsr   r*   r   r   r   test_sweep_2_jobs-   r,   z#LauncherTestSuite.test_sweep_2_jobsc                 C   s   t ttdd3 |d dd dd|d| ddg |d	 W d    n1 s'w   Y  W d    d S W d    d S 1 s?w   Y  d S )
NzQSweeping over Hydra's configuration is not supported : 'hydra.verbose=true,false')matchhydra.test_utils.a_moduleconfigscompose.yamlr$   +a=0,1zhydra.verbose=true,falsecalling_filecalling_moduler&   config_pathconfig_namer    r'   )r   r   reescaper*   r   r   r   !test_not_sweeping_hydra_overrides;   s2   "z3LauncherTestSuite.test_not_sweeping_hydra_overridesc                 C   r"   r#   r(   r*   r   r   r   test_sweep_1_job_strictX   r,   z)LauncherTestSuite.test_sweep_1_job_strictc                 C   sN   t t t|d| dg| |  |d W d    d S 1 s w   Y  d S )Nr$   zboo=barr%   )r   	Exceptionr)   r   r*   r   r   r   #test_sweep_1_job_strict_and_bad_keyf   s   
	"z5LauncherTestSuite.test_sweep_1_job_strict_and_bad_keyc                 C   r"   r#   )sweep_two_config_groupsr   r*   r   r   r   test_sweep_2_optimizersw   r,   z)LauncherTestSuite.test_sweep_2_optimizersc              	   C   s   d| dg}|d d|   dd|| |d}dgdgg}td	d
itd	dig}|A |jd us3J t|jd dks>J tdD ]!}	|jd |	 }
|
j||	 ksTJ |
j||	 ks]J t|
|
j qBW d    d S 1 sow   Y  d S )Nr$   group1=file1,file2r0   r1   unspecified_mandatory_defaultr4   group1=file1group1=file2foo
      r      )	r   r	   createreturnslenranger    cfgr   r   r   r   r    r!   base_overridessweepexpected_overridesexpected_confijob_retr   r   r   -test_sweep_over_unspecified_mandatory_default   s,   	"z?LauncherTestSuite.test_sweep_over_unspecified_mandatory_defaultc              	   C   s   d| ddg}|ddddd|| |d}d	dgd
dgg}dddddiddddddig}|A |j dus7J t|j d dksBJ tdD ]!}	|j d |	 }
|
j||	 ksXJ |
j||	 ksaJ t|
|
j qFW d   dS 1 ssw   Y  dS )a^  
        Tests that we can override things in the configs merged in only during the sweep config construction
        db.user=someone does not exist db_conf.yaml, and is only appear when we merge in db=mysql or db=postgresql.
        This presents a tricky situation when operating in strict mode, this tests verifies it's handled correctly.
        r$   zdb=mysql,postgresqlzdb.user=someoneNr0   r1   zdb_conf.yamlr4   zdb=mysqlzdb=postgresqldbmysqlsecretsomeone)driverpassworduser
postgresqldrowssaprF   )r\   rZ   r[   timeoutr   rH   )rJ   rK   rL   r    rM   r   rN   r   r   r   test_sweep_and_override   sF   
"z)LauncherTestSuite.test_sweep_and_overridec           
   	   C   s   d| g| }dt dtfdd}|d d|dd||d	}dtfd
d}td| |& |jd us2J |jd }	t|	dks?J |	d jdksHJ W d    d S 1 sSw   Y  d S )Nr$   cr   c                 S   s   | j S )N)x)ra   r   r   r   r      s   zDLauncherTestSuite.test_sweep_with_custom_resolver.<locals>.task_funcr0   r1   custom_resolverr4   c                   S   r   )NrE   r   r   r   r   r   my_custom_resolver   r   zMLauncherTestSuite.test_sweep_with_custom_resolver.<locals>.my_custom_resolverrd   r      rE   )r   r   r	   register_new_resolverrJ   rK   return_value)
r   r   r   r    r!   
overrides1r   rP   rd   rT   r   r   r   test_sweep_with_custom_resolver   s&   

"z1LauncherTestSuite.test_sweep_with_custom_resolver)__name__
__module____qualname__r   r   r   r   r   strr   r   r+   r.   r;   r<   r>   r@   rU   r`   ri   r   r   r   r   r      s    







2r   c                
   @   s.   e Zd Zdededee deddf
ddZdS )	BatchedSweeperTestSuiter   r   r    r!   r   Nc              	   C   s  ddg}d| g}| | | | |d dd dd||d}dd	gdd
gddgdd	gdd
gddgg}ddddddddddddddddddg}	t }
| |j}|d us[J t|d }| sgJ t|}|jjj	|ksuJ |j
d us|J t|j
dksJ |j
D ]
}t|dksJ qdd |j
D }t|dksJ t|D ]"\}}|j|| ksJ |j|	| ksJ |
|j t||j qW d    n1 sw   Y  t|
dksJ d S )NrA   zbar=100,200,300r$   r0   r1   r2   r4   rC   zbar=100zbar=200zbar=300rD   rF   r   rE   bar   i,  rG   multirun.yaml   rH   c                 S   s   g | ]	}|D ]}|qqS r   r   ).0batchrtr   r   r   
<listcomp>+  s    zGBatchedSweeperTestSuite.test_sweep_2_jobs_2_batches.<locals>.<listcomp>   )extendsetr'   r   existsr	   loadhydrar    taskrJ   rK   	enumeraterM   addworking_dirr   )r   r   r   r    r!   job_overrideshydra_overridesrP   rQ   rR   dirsr'   multirun_cfg_pathmultirun_cfgru   flatidxrT   r   r   r   test_sweep_2_jobs_2_batches   sb   




	

z3BatchedSweeperTestSuite.test_sweep_2_jobs_2_batches)rj   rk   rl   r   rm   r   r   r   r   r   r   r   rn      s    rn   r   r    r&   r'   r   c              	   C   s   | dd|dd||d}|i |j dusJ |j d }t|dks"J |d jg ks+J |d jdd	d
ks7J |d jjjjdksMJ d|d jjjj |d jjjjdusYJ |d jjjj	duseJ t
|j d d  W d   dS 1 syw   Y  dS )z#
    Runs a sweep with one job
    Nr0   r1   r2   r4   r   re   rF   r   ro   a_moduleUnexpected job name: )rJ   rK   r    rM   	hydra_cfgr}   jobnameidnumr   )r   r    r&   r'   rP   rT   r   r   r   r)   5  s,   	

"r)   c              	   C   s  dg}| | | dd|dd||d}ddd	d
}| |jdus#J |jdus*J t|j}|d }| s9J t|}|jjj	|ksGJ t
|jd	 dksRJ tdD ]l}	|jd	 |	 }
t|}|	|_|
jd|	 gksrJ |
j|ksyJ |
jjjjdksJ d|
jjjj |
jjjjdusJ |
jjjjdusJ t|
|
j |t|	 }dd | D }| sJ d| d| qVW d   dS 1 sw   Y  dS )z$
    Runs a sweep with two jobs
    r3   Nr0   r1   composer4   rF   r   r   )rE   rp   arr   rH   z+a=r   r   c                 S   s   g | ]}|  r|qS r   )is_dir)rt   rb   r   r   r   rw     s    z sweep_2_jobs.<locals>.<listcomp>'z' does not exist, dirs: )ry   r'   rJ   r   r{   r	   r|   r}   r    r~   rK   rL   rI   r   rM   r   r   r   r   r   r   rm   iterdir)r   r    r&   r'   r   rP   base_cfgr   r   rS   rT   rR   pathlstr   r   r   r-   V  sL   	
	


"r-   c           	   	   C   s   t |}|dg | dd|dd||d}dgdgg}td	d
dtdd
dg}|A |jdus6J t|jd dksAJ tdD ]!}|jd | }|j|| ksWJ |j	|| ks`J t
||j qEW d   dS 1 srw   Y  dS )zJ
    Make sure that optimizers=adam,nesterov is interpreted correctly
    rA   Nr0   r1   r   r4   rC   rD   rF   r   ro   rG   r   rH   )copydeepcopyry   r	   rI   rJ   rK   rL   r    rM   r   )	r   r    r&   r'   rP   rQ   rR   rS   rT   r   r   r   r?     s2   
		"r?   c                   @   s  e Zd Zdee fddZdedefddZdedee	 f fdd	Z
ed
edg ddddeddgddddeddddiiig ddddeddddiiidgddddgdededee	 de	de	dedee	 ddfdd Zed!edd"d#d$d%iig d&d'dei d(d)gd*d+dedd"d#d$d%iid(d)gd*d,ded"d-d.d%id/d0d1d2d3gd4d5ded-d.d%d6d7d8d9d:gd;iid<d/d0d=d>g d?d@dAdgdede	dee	 dBe	dedee	 ddfdCdDZdededee	 ddfdEdFZdededee	 ddfdGdHZdS )IIntegrationTestSuiter   c                 C   r   )z
        By default test applications working dir is tmpdir, override this method if that's not the case.
        This could be helpful when the tests kick off applications on remote machines.
        Nr   )r   r   r   r   get_test_app_working_dir     z-IntegrationTestSuite.get_test_app_working_dirr!   c                 C   s   |S )z~
        By default test applications will use tmpdir provided by the
        This can be customized by applications.
        r   )r   r!   r   r   r   get_test_scratch_dir  r   z)IntegrationTestSuite.get_test_scratch_dir.c                 C   s"   dt t dtdt t fdd}|S )z
        By default this does nothing, but it allows custom execution commands.
        Useful if the tests are not kicked off by python
        cmdfilenamer   c                 S   s   | S )z
            param cmd: old python commands in list of strings
            param filename: file name to be executed as main hydra module
            return: new commands to be executed in list of strings
            r   )r   r   r   r   r   fun  s   z5IntegrationTestSuite.generate_custom_cmd.<locals>.fun)r   rm   )r   r   r   r   r   generate_custom_cmd  s   z(IntegrationTestSuite.generate_custom_cmdz/task_config, overrides, filename, expected_nameNzno_config.py	no_config)r   zhydra.job.name=overridden_nameoverridden_namedifferent_filenamer}   r   r   name_from_config_filezwith_config.py0different_filename_and_config_file_name_overrideJdifferent_filename_and_config_file_name_override_and_command_line_overridetask_configr    r   expected_nametask_launcher_cfgextra_flagsc           	   	   C   sb   || }t |p	i }t |pi }t ||}t|tsJ t| |||d|||  d d S )NzHydraConfig.get().job.name)r!   r   r    printsexpected_outputsr   r   )r	   rI   merge
isinstancer   r   r   r   )	r   r!   r   r    r   r   r   r   rM   r   r   r   test_custom_task_name  s   %
z*IntegrationTestSuite.test_custom_task_namez$task_config, overrides, expected_dirrP   task_cfgztask_cfg_${hydra.job.num})dirsubdirztask_cfg/task_cfg_0sweep_dir_config_overridehydra.sweep.dir=cli_dir+hydra.sweep.subdir=cli_dir_${hydra.job.num}cli_dir/cli_dir_0sweep_dir_cli_override sweep_dir_cli_overridding_configr   z${hydra.job.override_dirname}hellorG   )r}   r   ba=1b=2zhydra_cfg/a=1,b=2zsubdir:override_dirnameconfigoverride_dirnamer   +seed)kv_sepitem_sepexclude_keys)rP   r   z???)r}   r   r   r   )r   r   zseed=10zhydra_cfg/a_1+b_2zsubdir:custom_override_dirnameexpected_dirc           
      C   s   || }t |p	i }t |pi }t ||}t|tsJ |  }|r.t| || nt| || }	t| |||dg d|	| 	 d d S )Nhydra.job.chdir=Trueos.getcwd()r!   r   r    r   r   r   )
r	   rI   r   r   r   r   rm   r   r   r   )
r   r!   r   r    r   r   r   rM   test_app_dirr   r   r   r   test_custom_sweeper_run_workdir  s$   ]
z4IntegrationTestSuite.test_custom_sweeper_run_workdirc                 C   sh   |}t |pi }t  }t ||}t|tsJ t| |||dtj	t
| ||  d d S )Nzhydra.utils.get_original_cwd()r   )r	   rI   r   r   r   r   r   osr   realpathrm   r   )r   r!   r   r   r    r   rM   r   r   r   test_get_orig_dir_multirunt  s   
z/IntegrationTestSuite.test_get_orig_dir_multirunc                 C   s   d}|g d }t |pi }t  }t ||}t|ts J ttd }t| 	|||d|| 
 d |  }	|	r?|	n|}
tjt| 	|d t| 	|
| g}t| 	|||ddg|| 
 d d S )	Nr   )r   r   r   z/foo/barz(hydra.utils.to_absolute_path('/foo/bar')r   zfoo/barz'hydra.utils.to_absolute_path('foo/bar')r   )r	   rI   r   r   r   rm   r   absoluter   r   r   r   r   r   r   )r   r!   r   r   r   r    r   rM   r   r   r   outputsr   r   r   test_to_absolute_path_multirun  s8   
z3IntegrationTestSuite.test_to_absolute_path_multirun)rj   rk   rl   r   r   r   r   r   r   rm   r   r
   parametrizer   r   r   r   r   r   r   r   r   r   r     s0   			
T
r   )#__doc__r   r   r9   pathlibr   typingr   r   r   r   r   	omegaconfr   r	   pytestr
   r   r   r}   r   hydra.errorsr   hydra.test_utils.test_utilsr   r   r   usefixturesr   rn   rm   r)   r-   r?   r   r   r   r   r   <module>   sf    ]@
!
4
#