
    0?iC                         d 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dlmZmZ ddlmZ ddlmZ dd	lmZmZ  G d
 de      Z G d de      Z G d de      Z G d de      Z G d de      Zy)z.
Tests for django_cronjob_utils base classes.
    )date	timedelta)patch	MagicMock)TestCase)timezone)CronTaskExecutionResult)ExecutionPattern)CronExecution)ValidationErrorConcurrentExecutionErrorc                   (    e Zd ZdZdZdZdedefdZy)TestTaskzTest task for base class tests.	test-taskA001r   returnc                     dddS )NFSuccess)errormessage selfr   s     ?/home/cursorai/projects/django-cronjob-utils/tests/test_base.pyexecutezTestTask.execute   s    955    N	__name__
__module____qualname____doc__	task_name	task_coder   dictr   r   r   r   r   r      s"    )II6D 6T 6r   r   c                   (    e Zd ZdZdZdZdedefdZy)FailingTaskzTask that always fails.zfailing-taskA002r   r   c                     ddddS )NTTask failedFAIL)r   r   
error_coder   r   s     r   r   zFailingTask.execute   s    -vNNr   Nr   r   r   r   r'   r'      s%    !IIOD OT Or   r'   c                   (    e Zd ZdZdZdZdedefdZy)ExceptionTaskzTask that raises exception.zexception-taskA003r   r   c                     t        d      )NTest exception)
ValueErrorr   s     r   r   zExceptionTask.execute(   s    )**r   Nr   r   r   r   r.   r.   "   s"    % II+D +T +r   r.   c                   (    e Zd ZdZdZdZdedefdZy)SkippedTaskz!Task that returns skipped result.zskipped-taskA004r   r   c                     t        dd      S )NTAlready processed)skippedreason)r
   r   s     r   r   zSkippedTask.execute2   s    t4GHHr   N)	r   r    r!   r"   r#   r$   r   r
   r   r   r   r   r4   r4   ,   s%    +IIID I_ Ir   r4   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d" Z$d# Z%d$ Z&d% Z'y&)'CronTaskBaseTestszTests for CronTask base class.c                 (    t        ddd      | _        y)zSet up test fixtures.i        N)r   execution_date)r   s    r   setUpzCronTaskBaseTests.setUp9   s    "4B/r   c                     t        | j                        }| j                  |j                  | j                         | j                  |j                  i        | j	                  |j
                         y)zTest task initialization.r?   N)r   r?   assertEqualoptionsassertIsNone	executionr   tasks     r   test_task_initializationz*CronTaskBaseTests.test_task_initialization=   sT    t':':;,,d.A.ABr*$..)r   c                     t        | j                  dd      }| j                  |j                  j	                  d             | j                  |j                  j	                  d             y)z&Test task initialization with options.T)r?   forcererunrK   rL   N)r   r?   
assertTruerD   getrG   s     r   %test_task_initialization_with_optionsz7CronTaskBaseTests.test_task_initialization_with_optionsE   sS    ..
 	((12((12r   c                 P    t        | j                        }|j                          y)z Test validation with valid date.rB   N)r   r?   validaterG   s     r   test_validate_successz'CronTaskBaseTests.test_validate_successP   s    t':':;r   c                     t        d      }| j                  t              5 }|j                          ddd       | j	                  dt        j                               y# 1 sw Y   /xY w)z'Test validation with invalid date type.z
2024-01-15rB   Nzdate object)r   assertRaisesr   rQ   assertInstr	exception)r   rH   cms      r   test_validate_invalid_datez,CronTaskBaseTests.test_validate_invalid_dateU   sL    |4/2MMO 0 	mS%67 0/s   A!!A*c                     t        | j                        }t        j                  |_        | j                  |j                                y)z8Test should_run with STANDARD pattern when not executed.rB   N)r   r?   r   STANDARDexecution_patternrM   
should_runrG   s     r   -test_should_run_standard_pattern_not_executedz?CronTaskBaseTests.test_should_run_standard_pattern_not_executed^   s3    t':':;!1!:!:)*r   c                     t         j                  j                  dd| j                  d       t	        | j                        }t
        j                  |_        | j                  |j                                y)z<Test should_run with STANDARD pattern when already executed.r   r   Tr$   r#   r?   	completedrB   N)
r   objectscreater?   r   r   r[   r\   assertFalser]   rG   s     r   1test_should_run_standard_pattern_already_executedzCCronTaskBaseTests.test_should_run_standard_pattern_already_executede   sb    $$!..	 	% 	
 t':':;!1!:!:*+r   c                     t         j                  j                  dd| j                  d       t	        | j                        }t
        j                  |_        | j                  |j                                y)z$Test should_run with ALWAYS pattern.r   r   Tr`   rB   N)
r   rb   rc   r?   r   r   ALWAYSr\   rM   r]   rG   s     r   test_should_run_always_patternz0CronTaskBaseTests.test_should_run_always_patterns   sb     	$$!..	 	% 	
 t':':;!1!8!8)*r   c                     t        | j                        }t        j                  |_        | j                  |j                                y)zITest should_run with RERUN_ON_FAILURE pattern when no previous execution.rB   N)r   r?   r   RERUN_ON_FAILUREr\   rM   r]   rG   s     r   ,test_should_run_rerun_on_failure_no_previousz>CronTaskBaseTests.test_should_run_rerun_on_failure_no_previous   s3    t':':;!1!B!B)*r   c                     t         j                  j                  dd| j                  dd       t	        | j                        }t
        j                  |_        | j                  |j                                y)zFTest should_run with RERUN_ON_FAILURE pattern when previous succeeded.r   r   Tr$   r#   r?   ra   successrB   N)
r   rb   rc   r?   r   r   rj   r\   rd   r]   rG   s     r   1test_should_run_rerun_on_failure_previous_successzCCronTaskBaseTests.test_should_run_rerun_on_failure_previous_success   se    $$!.. 	% 	
 t':':;!1!B!B*+r   c                     t         j                  j                  dd| j                  dd       t	        | j                        }t
        j                  |_        | j                  |j                                y)zCTest should_run with RERUN_ON_FAILURE pattern when previous failed.r   r   TFrm   rB   N
r   rb   rc   r?   r   r   rj   r\   rM   r]   rG   s     r   1test_should_run_rerun_on_failure_previous_failurezCCronTaskBaseTests.test_should_run_rerun_on_failure_previous_failure   sc    $$!.. 	% 	
 t':':;!1!B!B)*r   c                     t        | j                        }t        j                  |_        | j                  |j                                y)z*Test should_run with RATE_LIMITED pattern.rB   N)r   r?   r   RATE_LIMITEDr\   rM   r]   rG   s     r   $test_should_run_rate_limited_patternz6CronTaskBaseTests.test_should_run_rate_limited_pattern   s5    t':':;!1!>!> 	)*r   c                     t         j                  j                  dd| j                  d       t	        | j                  d      }t
        j                  |_        | j                  |j                                y)z"Test should_run with force option.r   r   Tr`   )r?   rK   N)
r   rb   rc   r?   r   r   r[   r\   rM   r]   rG   s     r   test_should_run_force_optionz.CronTaskBaseTests.test_should_run_force_option   sb    $$!..	 	% 	
 t':':$G!1!:!:)*r   c                     t         j                  j                  dd| j                  dd       t	        | j                  d      }t
        j                  |_        | j                  |j                                y)z"Test should_run with rerun option.r   r   Trm   )r?   rL   Nrq   rG   s     r   test_should_run_rerun_optionz.CronTaskBaseTests.test_should_run_rerun_option   se    $$!.. 	% 	
 t':':$G!1!B!B)*r   c                    t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       | j                  |j                  d       | j                  |j                  | j                         | j                  |j                         | j                  |j                         | j                  |j                  |       y)zTest creating execution record.rB   r   r   N)r   r?   create_execution_recordassertIsNotNoneidrC   r$   r#   rd   ra   rn   rF   r   rH   rF   s      r   test_create_execution_recordz.CronTaskBaseTests.test_create_execution_record   s    t':':;002	Y\\*,,f5,,k:1143F3FG,,-**+3r   c                     t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       y)z*Test execute_with_timeout without timeout.rB   r   N)r   r?   execute_with_timeoutrM   rn   rC   r   r   rH   results      r   $test_execute_with_timeout_no_timeoutz6CronTaskBaseTests.test_execute_with_timeout_no_timeout   sD    t':':;**,'3r   c                 
   t        | j                        }d|_        t        d      5 }t	        |d      r:t               |_        |j                         }| j                  |j                         ddd       y# 1 sw Y   yxY w)z'Test execute_with_timeout with timeout.rB   <   z django_cronjob_utils.base.signalSIGALRMN)
r   r?   timeoutr   hasattrr   r   r   rM   rn   )r   rH   mock_signalr   s       r   &test_execute_with_timeout_with_timeoutz8CronTaskBaseTests.test_execute_with_timeout_with_timeout   sd    t':':; 56+{I.&/k#224/	 766s   AA99Bc                     t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       | j                  |j                         y)z$Test execute with dict return value.rB   r   N)	r   r?   _executerM   rn   rC   r   rd   r8   r   s      r   test_execute_dict_returnz*CronTaskBaseTests.test_execute_dict_return   sS    t':':;'3(r   c                     t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       y)z/Test execute with ExecutionResult return value.rB   r7   N)r4   r?   r   rM   r8   rC   r9   r   s      r   $test_execute_execution_result_returnz6CronTaskBaseTests.test_execute_execution_result_return   sB    $*=*=>'(;<r   c                     t        | j                        }|j                         }| j                  |j                         | j                  d|j                         | j                  |j                  d       y)z Test execute exception handling.rB   r1   r2   N)	r.   r?   r   rd   rn   rU   r   rC   r,   r   s      r   test_execute_exception_handlingz1CronTaskBaseTests.test_execute_exception_handling   sX    D,?,?@(&7**L9r   c                     t        | j                        }|j                  t        d            }| j	                  |d       |j                  t        d            }| j	                  |d       y)zTest get_error_code method.rB   Testr2   RuntimeErrorN)r   r?   get_error_coder2   rC   r   )r   rH   r,   s      r   test_get_error_codez%CronTaskBaseTests.test_get_error_code  s\    t':':;((F);<
\2((f)=>
^4r   c                     t        | j                        }d|_        |j                          | j	                  |j                                y)z)Test should_retry when retry is disabled.rB   FN)r   r?   retry_on_failurer{   rd   should_retryrG   s     r   "test_should_retry_no_retry_enabledz4CronTaskBaseTests.test_should_retry_no_retry_enabled  s=    t':':; %$$&**,-r   c                     t        | j                        }d|_        d|_        |j	                          d|j
                  _        | j                  |j                                y)z+Test should_retry when max retries reached.rB   T   N)	r   r?   r   max_retriesr{   rF   retry_countrd   r   rG   s     r   %test_should_retry_max_retries_reachedz7CronTaskBaseTests.test_should_retry_max_retries_reached  sQ    t':':; $$$&%&"**,-r   c                     t        | j                        }d|_        d|_        |j	                          d|j
                  _        | j                  |j                                y)z*Test should_retry when within retry limit.rB   Tr   r=   N)	r   r?   r   r   r{   rF   r   rM   r   rG   s     r   test_should_retry_within_limitz0CronTaskBaseTests.test_should_retry_within_limit#  sO    t':':; $$$&%&"))+,r   c                 |    t        | j                        }d|_        | j                  |j	                                y)z2Test should_retry when no execution record exists.rB   TN)r   r?   r   rd   r   rG   s     r   %test_should_retry_no_execution_recordz7CronTaskBaseTests.test_should_retry_no_execution_record-  s1    t':':; $**,-r   c                 "   t        | j                        }|j                          |j                  j                  }|j                          |j                  j                          | j                  |j                  j                  |dz          y)zTest schedule_retry method.rB   r=   N)r   r?   r{   rF   r   schedule_retryrefresh_from_dbrC   )r   rH   initial_counts      r   test_schedule_retryz%CronTaskBaseTests.test_schedule_retry4  sh    t':':;$$&22&&(33]Q5FGr   c                    t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       | j                  |j                         t        j                  j                  d| j                        }| j                  |j                         | j                  |j                         y)z*Test run method with successful execution.rB   r   r   r$   r?   N)r   r?   runrM   rn   rC   r   rd   r8   r   rb   rN   ra   r   rH   r   rF   s       r   test_run_successful_executionz/CronTaskBaseTests.test_run_successful_execution?  s    t':':;'3( "))--.. . 
	 		++,	))*r   c                 B   t         j                  j                  dd| j                  d       t	        | j                        }t
        j                  |_        |j                         }| j                  |j                         | j                  |j                  d       y)z*Test run method when execution is skipped.r   r   Tr`   rB   zAlready executedN)r   rb   rc   r?   r   r   r[   r\   r   rM   r8   rC   r9   r   s      r   test_run_skipped_executionz,CronTaskBaseTests.test_run_skipped_executionP  s}    $$!..	 	% 	
 t':':;!1!:!:'(:;r   c                    t        | j                        }|j                         }| j                  |j                         | j                  |j                  d       | j                  |j                  d       t        j                  j                  d| j                        }| j                  |j                         | j                  |j                         y)z&Test run method with failed execution.rB   r*   r+   r(   r   N)r'   r?   r   rd   rn   rC   r   r,   r   rb   rN   rM   ra   r   s       r   test_run_failed_executionz+CronTaskBaseTests.test_run_failed_execution`  s    $*=*=>(7**F3 "))--.. . 
	 		++,**+r   c                    t        | j                        }| j                  t              5  |j	                          ddd       t
        j                  j                  d| j                        }| j                  |j                         | j                  |j                         | j                  |j                  d       y# 1 sw Y   xY w)z#Test run method exception handling.rB   Nr/   r   r2   )r.   r?   rT   r2   r   r   rb   rN   rM   ra   rd   rn   rC   r,   r~   s      r   test_run_exception_handlingz-CronTaskBaseTests.test_run_exception_handlingq  s    D,?,?@z*HHJ + "))--.. . 
	 		++,**+--|< +*s   CCc                     t         j                  j                  dd| j                  d       t	        | j                        }| j                  t              5  |j                          ddd       y# 1 sw Y   yxY w)z0Test run method with concurrent execution error.r   r   Fr`   rB   N)r   rb   rc   r?   r   rT   r   r   rG   s     r   #test_run_concurrent_execution_errorz5CronTaskBaseTests.test_run_concurrent_execution_error  se     	$$!..	 	% 	
 t':':;78HHJ 988s   A33A<c                 0   t        | j                        }d|_        d|_        |j	                         }| j                  |j                         t        j                  j                  d| j                        }| j                  |j                  d       y)z.Test run method with retry on failure enabled.rB   Tr   r(   r   r=   N)r'   r?   r   r   r   rd   rn   r   rb   rN   rC   r   r   s       r   test_run_with_retry_on_failurez0CronTaskBaseTests.test_run_with_retry_on_failure  s~    $*=*=> $(!))--.. . 
	 	..2r   c                    t        | j                        }d|_        d }||_        	 |j	                         }| j                  |       y# t        $ r t        j                  j                  d| j                        }| j                  |j                         | j                  |j                         | j                  |j                  d       Y yw xY w)zTest run method with timeout.rB   r=   c                 4    dd l }|j                  d       ddiS )Nr      r   F)timesleep)r   r   s     r   slow_executez=CronTaskBaseTests.test_run_with_timeout.<locals>.slow_execute  s    JJqMU##r   r   r   TIMEOUTN)r   r?   r   r   r   r|   TimeoutErrorr   rb   rN   rM   ra   rd   rn   rC   r,   )r   rH   r   r   rF   s        r   test_run_with_timeoutz'CronTaskBaseTests.test_run_with_timeout  s    t':':;	$
 $	>XXZF  ( 	>%--11 #22 2 I OOI//0Y../Y119=	>s   !A BCCc                    t        | j                        }|j                          t        dd      }t	        j
                  |d      5 }|j                  |       |j                  j                          ddd       y# 1 sw Y   yxY w)zTest notify_failure method.rB   FzTest failure)rn   r   _notification_managerN)r'   r?   r{   r
   r   objectnotify_failureassert_called_once)r   rH   r   mock_notifiers       r   test_notify_failurez%CronTaskBaseTests.test_notify_failure  si    $*=*=>$$& G \\$ 78M'((;;= 988s   
,A??Bc                     t        ddddd      }| j                  |j                         | j                  |j                  d       | j                  |j                         y)zTest ExecutionResult creation.Tr    F)rn   r   r,   r8   r9   N)r
   rM   rn   rC   r   rd   r8   r   r   s     r   test_execution_result_creationz0CronTaskBaseTests.test_execution_result_creation  sS     
 	'3(r   c                 ,   t               }| j                  |j                         | j                  |j                  d       | j                  |j
                  d       | j                  |j                         | j                  |j                  d       y)z$Test ExecutionResult default values.r   N)	r
   rM   rn   rC   r   r,   rd   r8   r9   r   s     r   test_execution_result_defaultsz0CronTaskBaseTests.test_execution_result_defaults  sj     "',**B/(+r   N)(r   r    r!   r"   r@   rI   rO   rR   rY   r^   re   rh   rk   ro   rr   ru   rw   ry   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   r;   r;   6   s    (0*	3
8+,++,++++44
0)=:5..-.	H+"< ,"= 3 >:
>),r   r;   N)r"   datetimer   r   unittest.mockr   r   django.testr   django.utilsr   django_cronjob_utils.baser	   r
   django_cronjob_utils.registryr   django_cronjob_utils.modelsr   django_cronjob_utils.exceptionsr   r   r   r'   r.   r4   r;   r   r   r   <module>r      sf    % *   ! ? : 5 U6x 6O( O+H +I( Ii, i,r   