
    j                    |   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
mZ ddlZddlmZmZmZmZ ddlmZmZ  ee      j-                         j.                  d   dz  d	z  ZddZddZd Zd Zej:                  j=                  d
g d      d        Zd Z d Z!ej:                  j=                  d
g d      d        Z"y)ur  tests/regression/test_collector_spawn_dry_run.py

task-2635 — REGISTERED→spawn expected · NOT_REGISTERED→no-spawn ·
subprocess 실호출 0.

Spec §5: REGISTERED status + cron_schedule_id 입력 → collector spawn
expected=true 단언 · NOT_REGISTERED 입력 → collector spawn expected=false 단언 ·
subprocess 실호출 0 (frozen fixture 기반 dry-run).
    )annotationsN)Path)decide_fallback_cancelexpected_collector_spawnexplain_fail_closedhas_durable_success_marker) NormalCallbackRegistrationStatusis_callback_complete   fixturesnormal_callback_registrationscenarioc                `    t        j                  t        | z  dz  j                  d            S )Nzevidence.jsonutf-8encodingjsonloadsFIXTURE_ROOT	read_textr   s    D/home/jay/workspace/tests/regression/test_collector_spawn_dry_run.py_load_evidencer   $   .    ::		 ?	2==w=O     c                `    t        j                  t        | z  dz  j                  d            S )Nzexpected.jsonr   r   r   r   s    r   _load_expectedr   *   r   r   c                 H   t        d      } | d   }t        j                  }|j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}x}}t        |       }d	}||u }|st	        j
                  d
|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}t        |       }d	}||u }|st	        j
                  d
|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}y )Nregistered_normalregistration_status==)zM%(py1)s == %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.REGISTERED
}.value
}r	   py1py3py5py7assert %(py9)spy9Tisz0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} is %(py6)sr   evpy0r%   r&   py6assert %(py8)spy8r
   )r   r	   
REGISTEREDvalue
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_nameAssertionError_format_explanationr   r
   )
r.   @py_assert0@py_assert4@py_assert6@py_assert2@py_format8@py_format10@py_assert5@py_format7@py_format9s
             r   'test_registered_normal_spawns_collectorrG   3   s   	+	,B#$Y(H(S(SY(S(Y(YY$(YYYYY$(YYYY$YYYYYY(HYYY(HYYY(SYYY(YYYYYYYY#B'/4/'4////'4//////#///#//////B///B///'///4///////#+t+#t++++#t+++++++++++++++++++++#+++t+++++++r   c                 r   t        d      } t        |       }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              nddt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d x}x}}t        |       }|j                  }d}||u }|st        j                  d|fd
||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|j                  }| d   }||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y )Nr    Tr+   r-   r   r.   r/   r2   r3   z7%(py2)s
{%(py2)s = %(py0)s.cancel_fallback
} is %(py5)sdecisionr0   py2r'   assert %(py7)sr(   cron_schedule_idr"   )z3%(py2)s
{%(py2)s = %(py0)s.schedule_id
} == %(py5)s)r   r   r6   r7   r9   r:   r;   r8   r<   r=   r   cancel_fallbackschedule_id)r.   rA   rD   r?   rE   rF   rJ   @py_assert1@py_assert3@py_format6rB   s              r   ;test_registered_normal_with_durable_marker_cancels_fallbackrT   :   s   	+	,B%b)1T1)T1111)T111111%111%111111b111b111)111T1111111%b)H##+t+#t++++#t++++++8+++8+++#+++t+++++++92&8#99#99999#999999989998999999#99999999r   )not_registered_envelope_onlysendfile_only_no_cronregister_failed_cli_errorc                F   t        |       }t        |      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              nddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}t        |      }d}||u }|st        j                  d|fd||f      d	t	        j
                         v st        j                  t              rt        j                  t              nd	dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}t        |      }|j                  }d}||u }	|	st        j                  d|	fd
||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
t        j                  |  d|j                   d      dz   d|
iz  }t        t        j                  |            d x}x}	}y )NFr+   r-   r   r.   r/   r2   r3   r
   rI   rJ   rK   z/: fail-closed must not cancel fallback (reason=)z
>assert %(py7)sr(   )r   r   r6   r7   r9   r:   r;   r8   r<   r=   r
   r   rO   _format_assertmsgreason)r   r.   rA   rD   r?   rE   rF   rJ   rQ   rR   rS   rB   s               r   0test_fail_closed_statuses_do_not_spawn_collectorr\   E   s    
	!B#B'050'50000'5000000#000#000000B000B000'00050000000#,u,#u,,,,#u,,,,,,,,,,,,,,,,,,,,,#,,,u,,,,,,,%b)H## u #u,  #u              $    (-    *CHOOCTTUV     r   c                    t        d      } | d   }t        j                  }|j                  }||k(  }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}x}x}}t        |       }d
}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d	x}x}}t        |       }d
}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d	x}x}}t        |       }
|
j                  }d}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |
      rt	        j                  |
      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}x}}y	)zSKIPPED is a success-status for fail-closed gating, but the collector
    DOES NOT spawn (no actual cron registration occurred).skipped_explicit_reason_dryrunr!   r"   )z_%(py1)s == %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.SKIPPED_WITH_EXPLICIT_REASON
}.value
}r	   r$   r)   r*   NFr+   r-   r   r.   r/   r2   r3   r
   TrI   rJ   rK   rM   r(   )r   r	   SKIPPED_WITH_EXPLICIT_REASONr5   r6   r7   r8   r9   r:   r;   r<   r=   r   r
   r   rO   )r.   r>   r?   r@   rA   rB   rC   rD   rE   rF   rJ   rQ   rR   rS   s                 r   :test_skipped_with_explicit_reason_does_not_spawn_collectorr`   W   s    
8	9B
 !+HHHNN!N	O !N   	"     ,   ,   I   O       $B'050'50000'5000000#000#000000B000B000'00050000000#,u,#u,,,,#u,,,,,,,,,,,,,,,,,,,,,#,,,u,,,,,,,%b)H##+t+#t++++#t++++++8+++8+++#+++t+++++++r   c                 4  
 ddl } g 
| j                  }
fd}|| _        	 dD ]9  }t        |      }t        |      }t	        |      }t        |      }t        |      }; 	 || _        g }
|k(  }|st        j                  d|fd
|f      dt        j                         v st        j                  
      rt        j                  
      ndt        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}}y# || _        w xY w)u   Reading fixtures and calling decision pure-functions must not invoke
    any subprocess. We patch subprocess.run to a tripwire and re-run the
    decision suite — any call would fail the test.
    r   Nc                 @    j                  | |f       t        d      )Nup   subprocess.run invoked during fixture-based decision suite — spec §7 (live cokacdir CLI 실호출 0) violated)appendr<   )argskwargstripwire_callss     r   tripwirezBtest_no_subprocess_call_during_fixture_decisions.<locals>.tripwires   s(    tVn-@
 	
r   r    rU   rV   rW   r^   r"   )z%(py0)s == %(py3)srf   )r0   r&   zassert %(py5)sr'   )
subprocessrunr   r   r
   r   r   r6   r7   r9   r:   r;   r8   r<   r=   )ri   real_runrg   r   r.   _rA   rQ   @py_format4rS   rf   s             @r   0test_no_subprocess_call_during_fixture_decisionsrn   i   s    
 N~~H
 JN"
 	(H  )B(,A$R(A&r*A#B'A	( "
>R>R>>R "
s   >D 	Drh   c           	     $   t        |       }t        |       }t        |      }|d   }t        |      }||u }|sSt	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd	|iz  }t        t	        j                  |            d x}x}x}}t        |      }|d
   }t        |      }||u }|sSt	        j
                  d|fd||f      d
t        j                         v st	        j                  t              rt	        j                  t              nd
dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd	|iz  }t        t	        j                  |            d x}x}x}}y )Ncollector_spawn_expectedr+   )zN%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} is %(py9)s
{%(py9)s = %(py5)s(%(py7)s)
}r   r.   bool)r0   r%   r&   r'   r(   r*   zassert %(py11)spy11r
   )r   r   r   rq   r6   r7   r9   r:   r;   r8   r<   r=   r
   )	r   r.   expectedrA   r@   @py_assert8r?   rC   @py_format12s	            r   2test_runtime_spawn_decision_matches_expected_fieldrv      s    
	!Bh'H#B'U9S0TU40T+UU'+UUUUU'+UUUUUUU#UUU#UUUUUUBUUUBUUU'UUUUUU4UUU4UUU0TUUU+UUUUUUUU#MH5K,LMt,L'MM#'MMMMM#'MMMMMMMMMMMMMMMMMMMMMM#MMMMMMtMMMtMMM,LMMM'MMMMMMMMr   )r   str)#__doc__
__future__r   builtinsr9   _pytest.assertion.rewrite	assertionrewriter6   r   pathlibr   pytestutils.anu_callback_fallbackr   r   r   r   utils.callback_envelope_schemar	   r
   __file__resolveparentsr   r   r   rG   rT   markparametrizer\   r`   rn   rv    r   r   <module>r      s    #       	N$$Q'$% ,: ,$" P 	N	Nr   