o
    iM                     @   s  U d dl Z d dlmZ d dlZd dlmZ d dlZd dlm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 d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm Z  d dlm!Z! d dlm"Z" d dl#m$Z$ d dl#m%Z% d dl#m&Z& d dl'm(Z( d dl)m*Z* d dl)m+Z+ d dl)m,Z, d dl-m.Z. d dl-m/Z/ d d l0m1Z1 d d!l0m2Z2 d d"l3m4Z4 d d#l5m6Z6 d d$l5m7Z7 d d%l8m9Z9 d d&l8m:Z: d d'l;m<Z< d d(l;m=Z= d d)l>m?Z? d d*l>m@Z@ d d+l>mAZA d d,lBmCZC d d-lDmEZE d d.lFmGZG d d/lHmIZI d d0lHmJZJ d d1lHmKZK d d2lHmLZL d d3lMmNZN eCeOZPd4ZQeReSd5< d6ZTeReSd7< d8ZUeVeSd9< d:d;iZWejXeYeYf eSd<< ejZeef Z[e\eYejZeYe\eYeYf f f Z]e^e Z_e`e	jaefZbg ebe%R Zcejdd=d>G d?d@ d@Zeejdd=d>G dAdB dBZfejdd=d>G dCdD dDZgejdd=d>G dEdF dFZhejdd=d>G dGdH dHZiG dIdJ dJeZjG dKdL dLeZkG dMdN dNeZlG dOdP dPeZmdQeldRendSefdTdUZodVeldSefdWdXZpdYe\eYeYf dSejqe\eYeEf  fdZd[Zrd\esel dSe^e[ fd]d^Zt	_dld`esel dRendSe^e[ fdadbZudcZvdSeVfdddeZwG dfdg dge jxZyG dhdi dieyZzG djdk dkeyZ{dS )m    N)	b64decode)RemoteDisconnected)JSONDecodeError)	TypedDict)uuid4)ITR_SKIPPING_LEVEL)TestId)TestModuleId)TestSuiteId)_get_normalized_cache_key)_read_from_cache)_write_to_cache)AGENTLESS_API_KEY_HEADER_NAME)AGENTLESS_DEFAULT_SITE)KNOWN_TESTS_ENDPOINT)REQUESTS_MODE)SETTING_ENDPOINT)SKIPPABLE_ENDPOINT)SUITE)TEST)TEST_MANAGEMENT_TESTS_ENDPOINT)CIVisibilityAPIClientError)CIVisibilityAPIServerError)#CIVisibilityAuthenticationException)GitData)APIRequestMetricNames)record_api_request)record_api_request_error)ERROR_TYPES)GIT_TELEMETRY)EARLY_FLAKE_DETECTION_TELEMETRY)(record_early_flake_detection_tests_count)record_settings_response)SKIPPABLE_TESTS_TELEMETRY)record_skippable_count)TEST_MANAGEMENT_TELEMETRY)"record_test_management_tests_count)combine_url_path)+fibonacci_backoff_with_jitter_on_exceptions)EVP_PROXY_AGENT_BASE_PATH)EVP_SUBDOMAIN_HEADER_API_VALUE)EVP_SUBDOMAIN_HEADER_NAME)
get_logger)CoverageLines)asbool)ConnectionType)Response)get_connection)
verify_url)	StopWatchg      .@DEFAULT_TIMEOUTg      4@DEFAULT_ITR_SKIPPABLE_TIMEOUT   DEFAULT_ATTEMPT_TO_FIX_RETRIESzContent-Typezapplication/json_BASE_HEADERST)frozenc                   @   sV   e Zd ZU dZeed< dZeed< dZeed< dZ	eed< d	Z
eed
< dZeed< dS )EarlyFlakeDetectionSettingsFenabled
   slow_test_retries_5s   slow_test_retries_10s   slow_test_retries_30s   slow_test_retries_5m   faulty_session_thresholdN)__name__
__module____qualname__r;   bool__annotations__r=   intr?   rA   rC   rE    rL   rL   ^/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/internal/ci_visibility/_api_client.pyr:   R   s   
 r:   c                   @   s*   e Zd ZU dZeed< eZeed< dZ	dS )TestManagementSettingsFr;   attempt_to_fix_retriesN)
rF   rG   rH   r;   rI   rJ   r7   rO   rK   __test__rL   rL   rL   rM   rN   \   s   
 rN   c                   @   s6   e Zd ZU dZeed< dZeed< dZeed< dZdS )TestPropertiesFquarantineddisabledattempt_to_fixN)	rF   rG   rH   rR   rI   rJ   rS   rT   rP   rL   rL   rL   rM   rQ   d   s
   
 rQ   c                   @   s   e Zd ZU dZdZeed< dZeed< dZeed< dZ	eed< dZ
eed< dZeed< dZeed< ejed	Zeed
< ejed	Zeed< dS )TestVisibilityAPISettingsFcoverage_enabledskipping_enabledrequire_gititr_enabledflaky_test_retries_enabledknown_tests_enabledcoverage_report_upload_enableddefault_factoryearly_flake_detectiontest_managementN)rF   rG   rH   rP   rV   rI   rJ   rW   rX   rY   rZ   r[   r\   dataclassesfieldr:   r_   rN   r`   rL   rL   rL   rM   rU   m   s   
 rU   c                   @   s\   e Zd ZU dZeje ed< dZeje	ee
f  ed< ejedZeejeef  ed< dS )ITRDataNcorrelation_idcovered_filesr]   skippable_items)rF   rG   rH   rd   tOptionalstrrJ   re   dictr-   ra   rb   setrf   Unionr   r
   rL   rL   rL   rM   rc   {   s   
 &rc   c                   @   s&   e Zd ZU eeef ed< eed< dS )_SkippableResponseMetacoveragerd   N)rF   rG   rH   rj   ri   rJ   rL   rL   rL   rM   rm      s   
 rm   c                   @   s8   e Zd ZU eed< eed< eed< eeejf ed< dS )$_SkippableResponseDataItemAttributesnamesuite
parametersconfigurationsN)rF   rG   rH   ri   rJ   rj   rg   AnyrL   rL   rL   rM   ro      s
   
 ro   c                   @   s   e Zd ZU eed< eed< dS )_SkippableResponseDataItemtype
attributesN)rF   rG   rH   ri   rJ   ro   rL   rL   rL   rM   ru      s   
 ru   c                   @   s"   e Zd ZU ee ed< eed< dS )_SkippableResponsedatametaN)rF   rG   rH   listru   rJ   rm   rL   rL   rL   rM   rx      s   
 rx   skippable_testignore_parametersreturnc                 C   sx   | d }|t krtd| dt  t| d d d }t|| d d }| d d }|r/d n| d d	}t|||S )
Nrv   
Test type  is not expected test type rw   rs   test.bundlerq   rp   rr   )r   
ValueErrorr	   r
   getr   )r|   r}   	test_type	module_idsuite_id	test_nametest_parametersrL   rL   rM    _get_test_id_from_skippable_test   s   r   skippable_suitec                 C   sJ   | d }|t krtd| dt  t| d d d }t|| d d S )Nrv   r   r   rw   rs   r   rq   )r   r   r	   r
   )r   
suite_typer   rL   rL   rM   "_get_suite_id_from_skippable_suite   s
   r   covered_files_datac              	   C   sv   i }d}|   D ]&\}}zttt|}|||< W q ty.   td| |d7 }Y qw |dkr9td| |S )Nr   z)Failed to parse coverage data for file %s   z!Failed to parse %d coverage files)	itemsr-   from_bytearray	bytearrayr   	Exceptionlogdebugwarning)r   re   parse_errorscovered_filecovered_lines_bytescovered_linesrL   rL   rM   _parse_covered_files   s   r   skippable_suites_datac              	   C   sv   t  }d}| D ]"}zt|}|| W q ty)   |d7 }tjd|dd Y qw |r2td| tt|t	 |S )Nr   r   z#Failed to parse skippable suite: %sTexc_infoz#Failed to parse %d skippable suites)
rk   r   addr   r   r   r   r$   lenr   )r   suites_to_skipcount_unparsed_suitesr   r   rL   rL   rM   _parse_skippable_suites   s   r   Fskippable_tests_datac              	   C   sx   t  }d}| D ]#}zt||}|| W q ty*   tjd|dd |d7 }Y qw |r3td| tt|t |S )Nr   z"Failed to parse skippable test: %sTr   r   z"Failed to parse %d skippable tests)	rk   r   r   r   r   r   r$   r   r   )r   r}   tests_to_skipcount_unparsed_testsr|   test_idrL   rL   rM   _parse_skippable_tests   s   
r   i'  c                  C   s\   zt tjdtt} W n ty   tdt t Y S w | dkr,td| t tS | S )z^Max pages for known tests pagination; configurable via _DD_CIVISIBILITY_KNOWN_TESTS_MAX_PAGES.&_DD_CIVISIBILITY_KNOWN_TESTS_MAX_PAGESzIFailed to parse _DD_CIVISIBILITY_KNOWN_TESTS_MAX_PAGES, using default: %sr   zO_DD_CIVISIBILITY_KNOWN_TESTS_MAX_PAGES must be positive (%s), using default: %s)	rK   osenvironr   ri   _DEFAULT_KNOWN_TESTS_MAX_PAGESr   r   r   )valuerL   rL   rM   _get_known_tests_max_pages   s"   r   c                   @   s  e Zd ZU dZeed< 			d*dededede	ee
jf de
je d	e
je d
e
je fddZejde	eef fddZejde	eef fddZde	eef fddZd+dededed
e
je def
ddZeded		d,dedede	ded
e
je dede
jfddZd-dedefd d!Z	d.d
e
je d#edede
je fd$d%Zd-dede
jee   fd&d'Z!d-dede
je	e e"f  fd(d)Z#dS )/_TestVisibilityAPIClientBasezClient for fetching test visibility settings from the CI Visibility API

    This class makes no direct references to environment variables, configs, or settings not passed to its
    constructor (except for default values).
    _requests_modeNbase_urlitr_skipping_levelgit_datars   
dd_servicedd_envtimeoutc                 C   s@   || _ || _|| _|| _|| _|| _|d ur|| _d S t| _d S N)	_base_url_itr_skipping_level	_git_data_configurations_service_dd_envr4   _timeout)selfr   r   r   rs   r   r   r   rL   rL   rM   __init__  s   
z%_TestVisibilityAPIClientBase.__init__r~   c                 C   s   dS )zjThis is an abstract method to force child classes to consider which headers should be redacted for loggingNrL   r   rL   rL   rM   _redact_headers  s   z,_TestVisibilityAPIClientBase._redact_headersc                 C   s   d S r   rL   r   rL   rL   rM   _get_headers  s   z)_TestVisibilityAPIClientBase._get_headersc                 C   s   t  }||   |S r   )r8   copyupdater   r   headersrL   rL   rM   _get_final_headers#  s   z/_TestVisibilityAPIClientBase._get_final_headersmethodendpointpayloadc              	   C   s   |d ur|n| j }|  }t| j|}d }z>t|}|j}	t||}td| j	j
||||   |d|	|| | }
td|
j t|
}|W |d urS|  S S |d ur]|  w w )NzSending %s request: %s %s %s %sPOSTzResponse status: %s)r   r   r'   r   r2   pathr1   r   r   r   rp   r   requestgetresponsestatusr0   from_http_responseclose)r   r   r   r   r   r   urlconn
parsed_urlurl_pathrespresponserL   rL   rM   _do_request(  s4   
	



z(_TestVisibilityAPIClientBase._do_requestr>   )attempts
exceptionsTmetric_namesread_from_cachec                 C   sx  t |}d}d|v rd|d v rt|||}|r)t|}	|	dur)td| |	S t }
|
  d}d}zzz| j||||d}W n t	yK   t
j} w |jdkrs|jdk rYt
jnt
j}|jd	krdt |jdkrnt|jt|jz0|
  |j}|durt|}t |}t|| |W W t||
 d
 ||d S t
j}td ty   t
j} w t||
 d
 ||d w )z
        Performs a request with telemetry submitted according to given names.
        Also uses the api responses cache layer.
         ry   rw   Nz2RESPONSE CACHE: Using cached response with key: %s)r   i  i  i  i  )response_byteserrorzResponse body is None)jsondumpsr   r   r   r   r3   startr   _NETWORK_ERRORSr   TIMEOUTr   CODE_4XXCODE_5XXr   r   r   stopbodyr   loadsr   r   elapsedBAD_JSONr   r   )r   r   r   r   r   r   r   str_payload	cache_keycached_responsesw
error_typer   r   response_bodyparsedrL   rL   rM   _do_request_with_telemetryE  sV   







z7_TestVisibilityAPIClientBase._do_request_with_telemetryc                 C   sH  t tjjtjjdtjjd}dtt d| jt	j
krt
nt| j| j| jj| jj| jj| jddi}| jdt||| j|d}d	|v rMt|jtj td
td| z|d d }|d }|d }|d }|d }	|d ptttd}
|d }| dd}|d d rt!|d d |d d d |d d d |d d d |d d d |d d d}nt! }| di }| dd}td }|r|" rt#|}td!| n| d"t$}td#| t%|pttd$|d%}W n t&y   t|jtj  w t'||||	|
||||d&	}t(|j)|j*|j+|j,|j-|j.|j/j0|j1j0d' |S )(zFetches settings from the test visibility API endpoint

        This raises encountered exceptions because fetch_settings may be used multiple times during a session.
        Ncountdurationr   r   ry   &ci_app_test_service_libraries_settings)
test_levelserviceenvrepository_urlshabranchrs   idrv   rw   r   )r   r   errorszGSettings response contained an error, disabling Intelligent Test RunnerzParsed API response: %srw   code_coveragetests_skippingrX   rY   rZ   _DD_TEST_FORCE_ENABLE_ATRr[   r\   Fr_   r;   slow_test_retries5s10s30s5mrE   )r;   r=   r?   rA   rC   rE   r`   )DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIESz>Number of Attempt to Fix retries obtained from environment: %drO   z6Number of Attempt to Fix retries obtained from API: %d%_DD_TEST_FORCE_ENABLE_TEST_MANAGEMENT)r;   rO   )	rV   rW   rX   rY   rZ   r[   r_   r`   r\   )rV   rW   rX   rY   rZ   r[   early_flake_detection_enabledtest_management_enabled)2r   r   SETTINGS_COUNTr   SETTINGS_MSSETTINGS_ERRORSri   r   r   r   r   r   r   r   r   r   
commit_shar   r   r   r   r   r   r   r   UNKNOWNr   r   r   r.   r   getenvr   r:   isdigitrK   r7   rN   KeyErrorrU   r"   rV   rW   rX   rY   rZ   r[   r_   r;   r`   )r   r   r   r   parsed_responserw   rV   rW   rX   rY   rZ   r[   r\   r_   test_management_attributesr  attempt_to_fix_retries_envrO   r`   api_settingsrL   rL   rM   fetch_settings  s   


	

z+_TestVisibilityAPIClientBase.fetch_settingsFignore_test_parametersc              
   C   s|  |d u rt }ttjjtjjtjjtjjd}dtt	 d| j
| j| jj| jj| j| jtjkr0tntddi}z| jdt||||d}W n
 tyN   Y d S w d }|d u rWd S |d}|d u rntd	 t|jtj d S |d
}	|	d u r}td ntd|	 |d}
|
d urt|
}|d}|d u rtd t|jtj d S | jtjkrt ||}nt!|}t"|	||dS )Nr   ry   test_params)r   r   r   r   rs   r   r   r   r   rz   zQSkippable tests response did not contain metadata field, no tests will be skippedrd   z/Skippable tests response missing correlation_idz+Skippable tests response correlation_id: %srn   z>Skippable tests request missing data, no tests will be skipped)rd   re   rf   )#r5   r   r#   REQUESTr   
REQUEST_MSRESPONSE_BYTESREQUEST_ERRORSri   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   )r   r   r  r   r   r   skippable_responsere   rz   rd   r   items_to_skip_dataitems_to_skiprL   rL   rM   fetch_skippable_items  sn   






z2_TestVisibilityAPIClientBase.fetch_skippable_itemsc              
   C   sH  t tjjtjjtjjtjjd}t }d }t }t	|D ]}|d u r$i nd|i}dt
t d| j| j| jj| j|ddi}z| jdt|||d}	W n tyU   Y  d S w d	|	v rit|jtj td
  d S z|	d d }
|
d }W n ty   t|jtj Y  d S w z*| D ]#\}}t|}| D ]\}}t||}|D ]
}|t|| qqqW n ty   tjddd t|jtj Y  d S w |
 d}|s nGt!|t"std t|jtj#  d S | d}|s n*| d}|std|d  t|jtj#  d S qtd| t|jtj# d S t$t%| |S )Nr   
page_statery   ci_app_libraries_tests_request)r   r   r   rs   	page_infor   r   r  r   z(Unique tests response contained an errorrw   testsz!Failed to parse unique tests dataTr   r'  z,Known tests response page_info is not a dicthas_nextcursorz9Known tests response missing pagination cursor on page %dr   z-Known tests pagination exceeded max pages: %d)&r   r    r  r   r  r  r   rk   r   rangeri   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r  r   r	   r
   r   r   r   
isinstancerj   r   r!   r   )r   r   r   known_test_idsr%  	max_pagespage_numberrequest_page_infor   r  rw   
tests_datamodulesuitesr   rq   r(  r   testresponse_page_infor)  rL   rL   rM   fetch_known_tests;  s   








z._TestVisibilityAPIClientBase.fetch_known_testsc              
   C   s  t tjjtjjtjjtjjd}i }dtt d| j	j
| j	j| j	j| j	jddi}z| jdt|||d}W n
 ty@   Y d S w d|v rSt|jtj td	 d S z
|d d
 d }W n tyn   t|jtj Y d S w zN| D ]G\}}t|}	|d }
|
 D ]6\}}t|	|}|d }| D ]$\}}t||}|di }t|dd|dd|ddd||< qqqtW n ty   tjddd t|jtj Y d S w tt| |S )Nr   ry   r&  )r   commit_messager   r   r   r   r  r   z1Test Management tests response contained an errorrw   modulesr3  r(  
propertiesrR   FrS   rT   )rR   rS   rT   z*Failed to parse Test Management tests dataTr   ) r   r%   r  r   r  r  r   ri   r   r   r   r7  r  r   r   r   r   r   r   r   r  r   r   r  r   r	   r
   r   r   rQ   r&   r   )r   r   r   test_propertiesr   r  r8  module_namemodule_datar   r3  
suite_name
suite_datar   r(  r   	test_datar   r9  rL   rL   rM   fetch_test_management_tests  sv   







z8_TestVisibilityAPIClientBase.fetch_test_management_tests)NNNr   )NT)T)NFT)$rF   rG   rH   __doc__r   rJ   ri   r   r   rj   rg   rt   rh   floatr   abcabstractmethodr   r   r   r0   r   r(   _RETRIABLE_ERRORSr   rI   r   rU   r  rc   r$  rk   r   r6  rQ   r@  rL   rL   rL   rM   r      st   
 
&
?n
I&Xr   c                       s   e Zd ZejZddddefdedede	de
deje
 deje
 deje
 d	eje
 d
ef fddZdd Zdee
e
f fddZ  ZS ) AgentlessTestVisibilityAPIClientNr   r   rs   api_keydd_siteagentless_urlr   r   r   c
              	      sR   |st d|d ur|nt}
|d ur|nd|
 }t |||||||	 || _d S )Nz8API key is required for AgentlessTestVisibilityAPIClientzhttps://api.)r   r   superr   _api_key)r   r   r   rs   rG  rH  rI  r   r   r   _dd_siter   	__class__rL   rM   r     s   
z)AgentlessTestVisibilityAPIClient.__init__c                 C   s
   t | jiS r   )r   rK  r   rL   rL   rM   r     s   
z-AgentlessTestVisibilityAPIClient._get_headersr~   c                 C   s   |   }d|t< |S )zSanitize headers for loggingREDACTED)r   r   r   rL   rL   rM   r     s   z0AgentlessTestVisibilityAPIClient._redact_headers)rF   rG   rH   r   AGENTLESS_EVENTSr   r4   r   r   _CONFIGURATIONS_TYPEri   rg   rh   rB  r   r   rj   r   __classcell__rL   rL   rM  rM   rF    s8    	
rF  c                       sx   e Zd ZejZddeefdede	de
dedeje deje ded	ef fd
dZdd Zdeeef fddZ  ZS )EVPProxyTestVisibilityAPIClientNr   r   rs   	agent_urlr   r   r   evp_proxy_base_urlc	           
   	      s&   t ||}	t |	|||||| d S r   )r'   rJ  r   )
r   r   r   rs   rT  r   r   r   rU  r   rM  rL   rM   r     s   
z(EVPProxyTestVisibilityAPIClient.__init__c                 C   s   t tiS r   )r+   r*   r   rL   rL   rM   r     s   z,EVPProxyTestVisibilityAPIClient._get_headersr~   c                 C   s   |   S )z;EVP proxy headers do not include authentication information)r   r   rL   rL   rM   r     s   z/EVPProxyTestVisibilityAPIClient._redact_headers)rF   rG   rH   r   EVP_PROXY_EVENTSr   r4   r)   r   r   rQ  ri   rg   rh   rB  r   r   rj   r   rR  rL   rL   rM  rM   rS    s2    	rS  )F)|rC  base64r   ra   http.clientr   r   r   r   sockettypingrg   r   uuidr   ddtrace.ext.test_visibilityr   1ddtrace.ext.test_visibility._test_visibility_baser   r	   r
   3ddtrace.internal.ci_visibility._api_responses_cacher   r   r   (ddtrace.internal.ci_visibility.constantsr   r   r   r   r   r   r   r   r   %ddtrace.internal.ci_visibility.errorsr   r   r   'ddtrace.internal.ci_visibility.git_datar   4ddtrace.internal.ci_visibility.telemetry.api_requestr   r   r   2ddtrace.internal.ci_visibility.telemetry.constantsr   r   >ddtrace.internal.ci_visibility.telemetry.early_flake_detectionr    r!   ,ddtrace.internal.ci_visibility.telemetry.gitr"   ,ddtrace.internal.ci_visibility.telemetry.itrr#   r$   8ddtrace.internal.ci_visibility.telemetry.test_managementr%   r&   $ddtrace.internal.ci_visibility.utilsr'   r(   $ddtrace.internal.evp_proxy.constantsr)   r*   r+   ddtrace.internal.loggerr,   /ddtrace.internal.test_visibility.coverage_linesr-   ddtrace.internal.utils.formatsr.   ddtrace.internal.utils.httpr/   r0   r1   r2   ddtrace.internal.utils.timer3   rF   r   r4   rB  rJ   r5   r7   rK   r8   Dictri   rl   _SKIPPABLE_ITEM_ID_TYPErj   rQ  rk   _KNOWN_TESTS_TYPETimeoutErrorr   r   rE  	dataclassr:   rN   rQ   rU   rc   rm   ro   ru   rx   rI   r   r   rh   r   r{   r   r   r   r   ABCr   rF  rS  rL   rL   rL   rM   <module>   s   
 

	


(	

   Y"