B
    `t                 @   s  d Z ddlmZmZmZ e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mZmZmZmZmZmZ ddlmZmZ ddlmZmZ dd	lmZmZ dd
lm Z m!Z! ddl"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( dZ)dddZ*G dd dZ+dddZ,dd Z-dS )z!Classify changes in Ansible code.    )absolute_importdivisionprint_functionN   )types)walk_module_targetswalk_integration_targetswalk_units_targetswalk_compile_targetswalk_sanity_targetsload_integration_prefixes'analyze_integration_target_dependencies)display	is_subdir)get_python_module_utils_importsget_python_module_utils_name)get_csharp_module_utils_importsget_csharp_module_utils_name)#get_powershell_module_utils_imports get_powershell_module_utils_name)
TestConfigIntegrationConfig)ChangeDescription)data_contextZ__focused__c                s  t | }t t t t t d ttt }t }t }t }x~|D ]v}tj|sf|| qJ|| ||}	|	sqJt	j
d|t|	f dd x$|	D ]}
t	j
|
dd ||
 qW qJW |t|8 }|rt	
dt|t|f  tt||B }t	
dt|  d}x|D ]~}||}|dkrdd	}t	j
d
| dd t| }t	d|  n|td	ox||k}tdd | D }|rtdd |D s|| rd|pdf }dkr |r tfdd|D s |r|d7 }|d7 }nd| }|s:|d7 }d}nd}| j|kr`t	j
d||f dd x8| D ],\}} | | |rj| | qjW qW |dkr| jdk rt	d|  xB D ]:} | d tdd  | D rtdg |< qW t fdd D  tfddD x& D ]} | dgkr:g  |< q:W t }|_t||_t||_ |_|_t||_|S )zx
    :type args: TestConfig
    :type paths: list[str]
    :type verbose_command: str
    :rtype: ChangeDescription
    )sanityunitsintegrationzwindows-integrationznetwork-integrationz&Expanded "%s" to %d dependent file(s):   )	verbosityzAExpanded %d changed file(s) into %d additional dependent file(s).z$Mapping %d changed file(s) to tests.r   NFz	%s -> allr   zPath not categorized: %sc             s   s   | ]\}}|r||fV  qd S )N ).0keyvaluer   r   T/home/dcms/DCMS/lib/python3.7/site-packages/ansible_test/_internal/classification.py	<genexpr>z   s    z%categorize_changes.<locals>.<genexpr>c             s   s   | ]}d |kV  qdS )r   Nr   )r    commandr   r   r#   r$   |   s    z%s: %snoner   c             3   s   | ]}| krd |kV  qdS )r   Nr   )r    r%   )verbose_commandr   r#   r$      s    z
 (focused)z (targeted)z%sz%s -> %sz+Omitted %d file(s) that triggered no tests.c             s   s   | ]}|d kV  qdS )allNr   )r    targetr   r   r#   r$      s    r(   c             3   s&   | ]} | r|t  | fV  qd S )N)sorted)r    c)commandsr   r#   r$      s    c             3   s   | ]}|t  | fV  qd S )N)r*   )r    r+   )focused_commandsr   r#   r$      s    ) 
PathMappersetcollectionsdefaultdictospathexistsaddget_dependent_pathsr   infolenr*   classify	all_testswarningpopFOCUSED_TARGETdictitemsanygetr   noticediscardr   r%   Zchanged_pathsdeleted_pathsZregular_command_targetsZfocused_command_targetsno_integration_paths)argspathsr'   ZmapperrD   Zoriginal_pathsZadditional_pathsrE   r3   Zdependent_pathsZdependent_pathZ
none_counttestsZfocused_targetresultr   r%   r)   changesr   )r,   r-   r'   r#   categorize_changes:   s    















rK   c               @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )r.   z,Map file paths to test commands and targets.c             C   s  || _ t| j | _tt | _tt | _tt | _	tt
 | _tt | _dd | jD | _dd | jD | _tdd | jD | _tdd | jD | _tdd | jD | _tdd | jD | _td	d | jD | _td
d | jD | _tdd | jD | _tdd | jD | _tdd | jD | _t | _t| j| _i | _i | _ i | _!i | _"xJ| jD ]@}x8|j#D ].}|| j"krt | j"|< | j"| $| qxW qlW dS )z(
        :type args: TestConfig
        c             S   s&   g | ]}t j|jd  dkr|qS )r   )z.ps1z.psm1)r2   r3   splitext)r    r)   r   r   r#   
<listcomp>   s    z'PathMapper.__init__.<locals>.<listcomp>c             S   s&   g | ]}t j|jd  dkr|qS )r   z.cs)r2   r3   rL   )r    r)   r   r   r#   rM      s    c             s   s   | ]}|j r|j V  qd S )N)module)r    r)   r   r   r#   r$      s    z&PathMapper.__init__.<locals>.<genexpr>c             s   s   | ]}|j D ]
}|V  qqd S )N)aliases)r    r)   ar   r   r#   r$      s    c             s   s   | ]}|j V  qd S )N)r3   )r    r)   r   r   r#   r$      s    c             s   s   | ]}|j |jfV  qd S )N)r3   rN   )r    r)   r   r   r#   r$      s    c             s   s   | ]}|j |fV  qd S )N)name)r    r)   r   r   r#   r$      s    c             s   s"   | ]}|j D ]}||fV  qqd S )N)rO   )r    r)   rP   r   r   r#   r$      s    c             s   s.   | ]&}d |j kr|jD ]}||jfV  qqdS )zposix/N)rO   modulesrQ   )r    r)   mr   r   r#   r$      s    c             s   s.   | ]&}d |j kr|jD ]}||jfV  qqdS )zwindows/N)rO   rR   rQ   )r    r)   rS   r   r   r#   r$      s    c             s   s.   | ]&}d |j kr|jD ]}||jfV  qqdS )znetwork/N)rO   rR   rQ   )r    r)   rS   r   r   r#   r$      s    N)%rF   get_integration_all_targetintegration_all_targetlistr   Zintegration_targetsr   Zmodule_targetsr
   compile_targetsr	   Zunits_targetsr   Zsanity_targetspowershell_targetscsharp_targetsr/   units_modulesunits_pathssanity_pathsr>   module_names_by_pathintegration_targets_by_nameintegration_targets_by_aliasposix_integration_by_modulewindows_integration_by_modulenetwork_integration_by_moduler   prefixesr   integration_dependenciespython_module_utils_importspowershell_module_utils_importscsharp_module_utils_importspaths_to_dependent_targetsZ
needs_filer5   )selfrF   r)   r3   r   r   r#   __init__   s:    zPathMapper.__init__c             C   st   t | |}t  }xV|rjt|}||O }t  }x6|D ].}| |}x|D ]}||krJ|| qJW q6W qW t|S )z;
        :type path: str
        :rtype: list[str]
        )r/   !get_dependent_paths_non_recursiverV   r5   r*   )ri   r3   Zunprocessed_pathsrG   Zqueued_pathsZqueued_pathZ	new_pathsnew_pathr   r   r#   r6      s    


zPathMapper.get_dependent_pathsc             C   s8   |  |}|dd | j|t D 7 }tt|}|S )z;
        :type path: str
        :rtype: list[str]
        c             S   s   g | ]}|j d  qS )/)r3   )r    r)   r   r   r#   rM     s    z@PathMapper.get_dependent_paths_non_recursive.<locals>.<listcomp>)get_dependent_paths_internalrh   rA   r/   r*   )ri   r3   rG   r   r   r#   rk      s    
z,PathMapper.get_dependent_paths_non_recursivec             C   s   t jt j|d d }t|t jjrb|dkr>| |S |dkrP| 	|S |dkrb| 
|S t|t jjr|| |S g S )z;
        :type path: str
        :rtype: list[str]
        r   z.pyz.psm1z.cs)r2   r3   rL   splitr   r   contentmodule_utils_pathget_python_module_utils_usage!get_powershell_module_utils_usageget_csharp_module_utils_usageintegration_targets_pathget_integration_target_usage)ri   r3   extr   r   r#   rn     s    



z'PathMapper.get_dependent_paths_internalc             C   s^   | j sHtd t }t| j| _ t }tdt| j || f  t|}t| j | S )z;
        :type path: str
        :rtype: list[str]
        z(Analyzing python module_utils imports...z1Processed %d python module_utils in %d second(s).)	re   r   r7   timer   rW   r8   r   r*   )ri   r3   beforeafterrQ   r   r   r#   rr     s    
z(PathMapper.get_python_module_utils_usagec             C   s^   | j sHtd t }t| j| _ t }tdt| j || f  t|}t| j | S )z;
        :type path: str
        :rtype: list[str]
        z,Analyzing powershell module_utils imports...z5Processed %d powershell module_utils in %d second(s).)	rf   r   r7   rx   r   rX   r8   r   r*   )ri   r3   ry   rz   rQ   r   r   r#   rs   .  s    
z,PathMapper.get_powershell_module_utils_usagec             C   sb   | j sLtd t }t| j| j| _ t }tdt| j || f  t|}t	| j | S )z;
        :type path: str
        :rtype: list[str]
        z$Analyzing C# module_utils imports...z-Processed %d C# module_utils in %d second(s).)
rg   r   r7   rx   r   rX   rY   r8   r   r*   )ri   r3   ry   rz   rQ   r   r   r#   rt   >  s    
z(PathMapper.get_csharp_module_utils_usagec             C   s0   | dd }dd t| j|t D }|S )z;
        :type path: str
        :rtype: list[str]
        rm      c             S   s(   g | ] }t jt jj|t jj qS r   )r2   r3   joinr   rp   ru   sep)r    r)   r   r   r#   rM   T  s   z;PathMapper.get_integration_target_usage.<locals>.<listcomp>)ro   r*   rd   rA   r/   )ri   r3   Ztarget_nameZ
dependentsr   r   r#   rv   N  s    z'PathMapper.get_integration_target_usagec             C   s4   |  |}|dkrdS || jkr0d|kr0||d< |S )zG
        :type path: str
        :rtype: dict[str, str] | None
        Nr   )	_classifyr\   )ri   r3   rI   r   r   r#   r9   Y  s    
zPathMapper.classifyc             C   s,   t  jjr| |S t  jjr(| |S dS )z-Return the classification for the given path.N)r   rp   Z
is_ansible_classify_ansibleZ
collection_classify_collection)ri   r3   r   r   r#   r~   j  s
    



zPathMapper._classifyc                s  t j|}t j|}t j|\}}i }t jj|krJ|dkrJt| jS t|dr^t| jS t|drl|S t|t	 j
jrt j|s|S | j|dd }|std|  |S d|jkr|S dd	|jkr|jnd
dd|jkr|jnd
dd|jkr|jnd
tdiS t|t	 j
jr|t	 j
jkrxNdD ]F}||krX|dkrX|| jiS ||d kr6|dkr6|| jiS q6W | j| j| jdS t|t	 j
jrddiS t|t	 j
jr|| jkrd|iS t j|}	x4|	r|	d | jkrd|	d iS t j|	}	qW t|t	 j
jr| j|}
|
rd|
| jkrJ|
nd
d|dkrd| j|
nd
d|dkr~| j|
nd
d| j|
tdiS |S t|t	 j
j r|dkr|S |dkr|S |dkr|S t|t	 j
j!d r|dkr|"dr@d|dd
   t# fdd | j$D r4 dd!S | jdd!S | j%|d"krX|}nl|&d#r| j%|d
d$ d"kr|d
d$ }n8|&d%r| j%|d
d& d"kr|d
d& }nd
}|rd'|   | j$kr dd!S tjd(  dd) ddiS t|t	 j
j!d* r|d+kr6| j| j| jd,d-S d.| }|| jkrNd
}d/| }|| jkrfd
}d0| }|| jkr~d
}|d1kr| j|d2S |d3kr| j| j|d4S |d5kr| j|d!S |d6kr|| j|d4S |||d7S t|t	 j
j!d8 rddiS t|t	 j
j!d9 r|d+kr0t| jS d:d;d<d=d>g}||krTt'| j}nd
}| jd?| }d@| }|| jkrd
}d|rd	|jkr|jn|d|rd|jkr|jnd
d|rd|jkr|jnd
d|t|d
k	iS t|t	 j
j!dA r| (dA|S t|t	 j
j!dB r(| (dB|S t|t	 j
j!dC sjt|t	 j
j!dD sjt|t	 j
j!dE r|dkr|| j%kr| j%| d"krd'|   | j$kr dd!S tjd(  dd) ddiS | jdd!S t|t	 j
j!dF r| (dF|S d
S )GzOReturn the classification for the given path using rules common to all layouts.)zazure-pipelines.ymlzshippable.ymlz.azure-pipelinesz.githubrm   r{   zUnexpected non-target found: %szhidden/r   zposix/Nzwindows-integrationzwindows/znetwork-integrationznetwork/T)r   zwindows-integrationznetwork-integrationz.cfgz.requirementsz.txtr   r(   r   z.py)z.csz.ps1z.csz.psm1actionZnet_znetwork/.*_%s   c             3   s   | ]}t d   |V  qdS )z^%s$N)research)r    alias)network_targetr   r#   r$     s    z.PathMapper._classify_common.<locals>.<genexpr>)znetwork-integrationr   network_configi	_templateiznetwork/%s/z%Integration tests for "%s" not found.)unique
connectionrj   ztest/units/plugins/connection/)r   zwindows-integrationznetwork-integrationr   z(test/units/plugins/connection/test_%s.pyzconnection_%szconnection_windows_%s)ZwinrmZpsrp)zwindows-integrationr   local)r   znetwork-integrationr   Znetwork_cliZparamiko_ssh)r   zwindows-integrationr   Zdoc_fragmentsZ	inventoryZ	host_listscriptZyamlZiniautozinventory_%sz'test/units/plugins/inventory/test_%s.pyfilterlookupZterminalZcliconfZnetconftest))r2   r3   dirnamebasenamerL   r}   r:   rF   r   r   rp   ru   r4   r^   rA   ro   r   r;   rO   rQ   r=   Zintegration_pathrU   Zsanity_path	unit_pathr[   module_pathr]   rZ   r`   ra   rb   rq   Zplugin_paths
startswithr@   r_   rc   endswithrT   _simple_plugin_tests)ri   r3   r   filenamerQ   rw   minimalr)   r%   Z	test_pathmodule_nameZnetwork_platform
units_pathintegration_nameZwindows_integration_nameZtest_allZposix_integration_fallbackr   )r   r#   _classify_commont  s>   










&&








zPathMapper._classify_commonc             C   sv   |  |}|dk	r|S tj|}tj|\}}i }|drD|S |drR|S d|krr|dkrf|S |dkrr|S dS )zQReturn the classification for the given path using rules specific to collections.Nzchangelogs/zdocs/rm   )z
.gitignoreCOPYINGLICENSEMakefile)z.inz.mdz.rstz.tomlz.txt)r   r2   r3   r   rL   r   )ri   r3   rI   r   dummyrw   r   r   r   r#   r     s$    


zPathMapper._classify_collectionc             C   s  | drddiS | |}|dk	r(|S tj|}tj|}tj|\}}i }| drht| jS | drv|S | drddiS | d	r|S | d
r|dkrddiS |S | dr|S | drd}|| j	krd}| j
|dS | drt| jS | dr|S | dr| dr| drz|dkrz|ddd }	d|	 f}
x"|
D ]}|| jkr\d|iS q\W t| jS |S | dr|S | dr| drd|dd d d!  }|| jkrd|iS | d"r|d#krt| jd$d%S | d&r6d| }|| jkr,d|iS t| jS | d'rLd(d)d*S | d+rbd(d)d*S | d,rxd(d)d-S | d.rd(d)d-S | d/rd(d)d-S | d0r|d1kr|| j
iS |d2kr|d(iS | d3rd|d d  }|| jkrd|iS | d4rt| jS | d5r4t| jS | d6r|d7krd8d9d:d9d;d<d=d>}||}|r|d?\}}||iS d| }|| jkrd|iS t| jS | d@r|S dA|kr|dBkr|S |dCkrt| jS |dDkr|S dS )EzMReturn the classification for the given path using rules specific to Ansible.ztest/units/compat/r   ztest/units/Nzbin/zchangelogs/zcontrib/ztest/units/contrib/zdocs/z	examples/z0examples/scripts/ConfigureRemotingForAnsible.ps1zwindows-integrationZconnection_winrmzhacking/z lib/ansible/executor/powershell/ztest/units/executor/powershell/)zwindows-integrationr   zlib/ansible/z	licenses/z
packaging/zpackaging/requirements/zrequirements-z.txt-r   z	cloud/%s/r   ztest/ansible_test/ztest/lib/ansible_test/config/zcloud-config-r   .r   z'test/lib/ansible_test/_data/completion/z1test/lib/ansible_test/_data/completion/docker.txtT)forcez&test/lib/ansible_test/_internal/cloud/z'test/lib/ansible_test/_internal/sanity/r(   zansible-test)r   r   z#test/lib/ansible_test/_data/sanity/z&test/lib/ansible_test/_internal/units/)r   r   z"test/lib/ansible_test/_data/units/z#test/lib/ansible_test/_data/pytest/z)test/lib/ansible_test/_data/requirements/)r   znetwork-integrationzwindows-integration)r   r   zintegration.cloud.z	test/lib/ztest/support/ztest/utils/shippable/ztest/utils/shippablezintegration:cloud/zintegration:allznetwork-integration:allz
sanity:allz	units:allzwindows-integration:all)zcloud.shzlinux.shz
network.shz	remote.shz	sanity.shzunits.shz
windows.sh:ztest/utils/rm   )z.gitattributesz
.gitignorez.mailmapr   r   )zsetup.py)z.inz.mdz.rstz.tomlz.txt)r   r   r2   r3   r   r   rL   r:   rF   r[   rU   ro   r_   rA   )ri   r3   rI   r   r   rQ   rw   r   r   	component
candidates	candidateZcloud_targetZtest_mapZ
test_matchZtest_commandZtest_targetr   r   r#   r     s    

























zPathMapper._classify_ansiblec             C   sn   |dkrt | jdS | jd||f }|r4|j}nd}tjt j	j
d|d| }|| jkrbd}t||dS )z
        Return tests for the given plugin type and plugin name.
        This function is useful for plugin types which do not require special processing.
        rj   Tz%s_%sNZpluginsz
test_%s.py)r   r   )r:   rF   r^   rA   rQ   r2   r3   r|   r   rp   r   r[   r>   )ri   Zplugin_typeZplugin_nameZintegration_targetr   r   r   r   r#   r     s    
zPathMapper._simple_plugin_testsN)__name__
__module____qualname____doc__rj   r6   rk   rn   rr   rs   rt   rv   r9   r~   r   r   r   r   r   r   r   r#   r.      s$   .
  & dr.   Fc             C   s"   |r
d}nt | }dd|||dS )zQ
    :type args: TestConfig
    :type force: bool
    :rtype: dict[str, str]
    r(   )r   r   r   zwindows-integrationznetwork-integration)rT   )rF   r   rU   r   r   r#   r:     s    r:   c             C   s   t | tr| jS dS )z0
    :type args: TestConfig
    :rtype: str
    r(   )
isinstancer   Zchanged_all_target)rF   r   r   r#   rT     s    
rT   )N)F).r   
__future__r   r   r   type__metaclass__r0   r2   r   rx    r   tr)   r   r   r	   r
   r   r   r   utilr   r   Zimport_analysisr   r   Zcsharp_import_analysisr   r   Zpowershell_import_analysisr   r   configr   r   metadatar   datar   r=   rK   r.   r:   rT   r   r   r   r#   <module>   s4   $

}      
