a
    kÄ#dÈ%  ã                   @   sX  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
mZmZ d dlmZmZ d dlm  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r¦d d	lmZ eeef Zeed
eeef ge f Z!eed
ge f Z"e	e!eeef ee" f Z#e $e j%¡G dd„ dƒƒZ&G dd„ de&ƒZ'e $e j%¡G dd„ dƒƒZ(e $e j%¡G dd„ dƒƒZ)dS )é    N)Údefaultdict)	ÚAnyÚUnionÚListÚOptionalÚDictÚTupleÚSetÚCallableÚTYPE_CHECKING)Úmake_lined_tableÚSingleConversationSocket)ÚSuperSocket)Ú_Edge)ÚEcuStateÚEcuResponse)ÚScapy_Exception)Ú'AutomotiveTestCaseExecutorConfigurationr   c                   @   s„   e Zd ZdZi ZdZejdd„ ƒZejdd„ ƒZ	ejdd„ ƒZ
ejd	d
„ ƒZejddd„ƒZeejdd„ ƒƒZeejdd„ ƒƒZdS )ÚAutomotiveTestCaseABCaá  
    Base class for "TestCase" objects. In automotive scanners, these TestCase
    objects are used for individual tasks, for example enumerating over one
    kind of functionality of the protocol. It is also possible, that
    these TestCase objects execute complex tests on an ECU.
    The TestCaseExecuter object has a list of TestCases. The executer
    manipulates a device under test (DUT), to enter a certain state. In this
    state, the TestCase object gets executed.
    Ú c                 C   s
   t ƒ ‚dS )z¹
        Tells if this TestCase was executed for a certain state
        :param state: State of interest
        :return: True, if TestCase was executed in the questioned state
        N©ÚNotImplementedError©ÚselfÚstate© r   úa/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/automotive/scanner/test_case.pyÚhas_completed1   s    z#AutomotiveTestCaseABC.has_completedc                 C   s
   t ƒ ‚dS )aO  
        Will be executed previously to ``execute``. This function can be used
        to manipulate the configuration passed to execute.

        :param socket: Socket object with the connection to a DUT
        :param state: Current state of the DUT
        :param global_configuration: Configuration of the TestCaseExecutor
        Nr   ©r   Úsocketr   Zglobal_configurationr   r   r   Úpre_execute;   s    z!AutomotiveTestCaseABC.pre_executec                 K   s
   t ƒ ‚dS )a  
        Executes this TestCase for a given state

        :param socket: Socket object with the connection to a DUT
        :param state: Current state of the DUT
        :param kwargs: Local configuration of the TestCasesExecutor
        :return:
        Nr   ©r   r   r   Úkwargsr   r   r   ÚexecuteK   s    zAutomotiveTestCaseABC.executec                 C   s
   t ƒ ‚dS )aP  
        Will be executed subsequently to ``execute``. This function can be used
        for additional evaluations after the ``execute``.

        :param socket: Socket object with the connection to a DUT
        :param state: Current state of the DUT
        :param global_configuration: Configuration of the TestCaseExecutor
        Nr   r   r   r   r   Úpost_executeX   s    z"AutomotiveTestCaseABC.post_executeFTc                 C   s
   t ƒ ‚dS )aÆ  
        Shows results of TestCase

        :param dump: If True, the results will be returned; If False, the
                     results will be printed.
        :param filtered: If True, the negative responses will be filtered
                         dynamically.
        :param verbose: If True, additional information will be provided.
        :return: test results of TestCase if parameter ``dump`` is True,
                 else ``None``
        Nr   )r   ÚdumpÚfilteredÚverboser   r   r   Úshowh   s    zAutomotiveTestCaseABC.showc                 C   s   t ‚dS )zy
        Tells if this TestCase is completely executed
        :return: True, if TestCase is completely executed
        Nr   ©r   r   r   r   Ú	completedx   s    zAutomotiveTestCaseABC.completedc                 C   s   t ‚dS )zl
        Tells the supported responses in TestCase
        :return: The list of supported responses
        Nr   r)   r   r   r   Úsupported_responses‚   s    z)AutomotiveTestCaseABC.supported_responsesN)FTF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_supported_kwargsÚ_supported_kwargs_docÚabcÚabstractmethodr   r    r#   r$   r(   Úpropertyr*   r+   r   r   r   r   r   "   s&   

	


r   c                   @   s†   e Zd ZdZd ZejZejZdd„ Zdd„ Z	e
dd„ ƒZedd	„ ƒZed
d„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zddd„ZdS )ÚAutomotiveTestCasez Base class for TestCasesc                 C   s   t tƒ| _d S ©N)r   ÚboolÚ_state_completedr)   r   r   r   Ú__init__”   s    zAutomotiveTestCase.__init__c                 C   s
   | j | S r6   ©r8   r   r   r   r   r   ˜   s    z AutomotiveTestCase.has_completedc                 C   sŽ   |  ¡ D ]€\}}|| j ¡ vr0td|| jf ƒ‚| j| \}}|d urdt||ƒsdtd|t|ƒf ƒ‚|d ur||ƒstd|t|ƒf ƒ‚qd S )Nz(Keyword-Argument %s not supported for %sz-Keyword-Value '%s' is not instance of type %sz<Validation Error: '%s: %s' is not in the allowed value range)Úitemsr0   Úkeysr   r,   Ú
isinstanceÚstr)Úclsr"   ÚkÚvÚtiZvfr   r   r   Úcheck_kwargsœ   s(    ÿÿ
ÿÿ
ÿÿzAutomotiveTestCase.check_kwargsc                 C   s   t dd„ | j ¡ D ƒƒS )Nc                 s   s   | ]\}}|V  qd S r6   r   )Ú.0Ú_rA   r   r   r   Ú	<genexpr>²   ó    z/AutomotiveTestCase.completed.<locals>.<genexpr>)Úallr8   r;   r)   r   r   r   r*   ¯   s    zAutomotiveTestCase.completedc                 C   s   t | j ¡ ƒS )z_
        Helper function to get all scanned states
        :return: all scanned states
        )Úsetr8   r<   r)   r   r   r   Úscanned_states´   s    z!AutomotiveTestCase.scanned_statesc                 C   s   d S r6   r   r   r   r   r   r    ½   s    zAutomotiveTestCase.pre_executec                 K   s
   t ƒ ‚d S r6   r   r!   r   r   r   r#   Á   s    zAutomotiveTestCase.executec                 C   s   d S r6   r   r   r   r   r   r$   Å   s    zAutomotiveTestCase.post_executec                 K   sN   ddt | jƒd   d }|d| j d 7 }|dt | jƒd  d 7 }|d S )Nz

ú=é
   Ú
z     ú-)ÚlenÚ_description)r   r"   Úsr   r   r   Ú_show_headerÉ   s    zAutomotiveTestCase._show_headerc                    s*   ‡ fdd„ˆ j D ƒ}t|dd„ dd�p(dS )Nc                    s   g | ]}|ˆ j | f‘qS r   r:   )rD   r   r)   r   r   Ú
<listcomp>Ó   s   ÿz>AutomotiveTestCase._show_state_information.<locals>.<listcomp>c                 S   s   d| d | d fS )NzScan state completedr   é   r   )Útupr   r   r   Ú<lambda>Ö   rG   z<AutomotiveTestCase._show_state_information.<locals>.<lambda>T)r%   r   )rJ   r   )r   r"   r*   r   r)   r   Ú_show_state_informationÑ   s    
ÿþþz*AutomotiveTestCase._show_state_informationFTc                 C   s4   |   ¡ }|r||  ¡ 7 }|r$|d S t|ƒ d S d S )NrM   )rR   rW   Úprint)r   r%   r&   r'   rQ   r   r   r   r(   Ù   s    zAutomotiveTestCase.showN)FTF)r,   r-   r.   r/   rP   r   r0   r1   r9   r   ÚclassmethodrC   r4   r*   rJ   r    r#   r$   rR   rW   r(   r   r   r   r   r5   �   s$   


r5   c                   @   s   e Zd Zejdd„ ƒZdS )ÚTestCaseGeneratorc                 C   s
   t ƒ ‚d S r6   r   r)   r   r   r   Úget_generated_test_caseê   s    z)TestCaseGenerator.get_generated_test_caseN)r,   r-   r.   r2   r3   r[   r   r   r   r   rZ   è   s   rZ   c                   @   s(   e Zd Zejdd„ ƒZejdd„ ƒZdS )ÚStateGeneratorc                 C   s   t ‚d S r6   r   )r   r   Úconfigr   r   r   Úget_new_edgeó   s    zStateGenerator.get_new_edgec                 C   s   t ‚dS )a�  

        :param socket: Socket to target
        :param edge: Tuple of EcuState objects for the requested
                     transition function
        :return: Returns an optional tuple consisting of a transition function,
                 a keyword arguments dictionary for the transition function
                 and a cleanup function. Both functions
                 take a Socket and the TestCaseExecutor configuration as
                 arguments and return True if the execution was successful.
                 The first function is the state enter function, the second
                 function is a cleanup function
        Nr   )r   r   Úedger   r   r   Úget_transition_functionø   s    z&StateGenerator.get_transition_functionN)r,   r-   r.   r2   r3   r^   r`   r   r   r   r   r\   ð   s   
r\   )*r2   Úcollectionsr   Zscapy.compatr   r   r   r   r   r   r	   r
   r   Zscapy.utilsr   r   Zscapy.libs.sixZlibsÚsixZscapy.supersocketr   Z&scapy.contrib.automotive.scanner.graphr   Zscapy.contrib.automotive.ecur   r   Zscapy.errorr   Z.scapy.contrib.automotive.scanner.configurationr   Z_SocketUnionr>   r7   Z_TransitionCallableZ_CleanupCallableZ_TransitionTupleÚadd_metaclassÚABCMetar   r5   rZ   r\   r   r   r   r   Ú<module>
   s*   ,
j[

