
    iv                        d Z ddlZddlmc mZ ddl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ZdZeej                   vrej                   j#                  de       dej                   vrej                   j#                  dd       dej                   vrej                   j#                  dd       ddlmZ ddlmZ dd	lmZ dd
lmZmZmZ ej                   j;                  edd      Zej                   j;                  edd      Zh dZ  ejB                         d        Z"de#de$fdZ%de#de$fdZ& G d d      Z' G d d      Z( G d d      Z) G d d      Z* G d d      Z+ G d  d!      Z, G d" d#      Z- G d$ d%      Z. G d& d'      Z/y)(u  
test_quality_gates_integration.py — Dispatch Quality Gates 파이프라인 통합 테스트 (벨레스)

8개 시나리오로 개별 컴포넌트들이 함께 올바르게 동작하는지 검증.
- Scenario 1: "확인 불가" 보고서 → l1_smoketest FAIL
- Scenario 2: 수정 파일 심볼 역추적 → 미수정 파일 WARN
- Scenario 3: pytest FAIL → ci_preflight FAIL
- Scenario 4: goal_assertions 전부 PASS → GOAL-GATE PASS
- Scenario 5: goal_assertions 1개 FAIL → GOAL-GATE BLOCKED
- Scenario 6: 미해결 이슈 4개 → unresolved_gate BLOCK
- Scenario 7: gate-config mode=warn → WARN만 (block 없음)
- Scenario 8: 백틱 토큰 자동 추출 → affected_files 자동 주입
    N)Pathz/home/jay/workspacez/home/jay/workspace/scriptsz*/home/jay/workspace/teams/shared/verifiers)scan)verify)_auto_inject_affected_files)load_gate_configis_gate_enabledget_gate_modeconfigzgate-config.jsonscriptszci_preflight.sh>	   jqcatnpmnpxtsccurlgreppytestpython3c               #      K   t        t              j                  d      } d t        t              j                  | d       yw)uX   gate-config.json 내용을 백업하고, 테스트 종료 후 원본으로 복원한다.utf-8encodingN)r   GATE_CONFIG_PATH	read_text
write_text)original_contents    ;/home/jay/workspace/tests/test_quality_gates_integration.pygate_config_backupr   :   s?      ,-777I		%%&6%Is   AAtask_file_pathreturnc                 :   t        d      sdt        d      g dS t        d      }t        t        d      j	                  dt        t                          }t        | dd      5 }|j                         }ddd       t        j                  d	t        j                        }g }d
}|r|j                  d      j                         }|j                  d      D ]  }	t        j                  d|	      }
|
s|
j                  d      j                         }|s>|j                         d   }||vrVt        j                   |ddd      }|j#                  ||j$                  f       |j$                  dk7  sd} |r|dk(  }|rdnd||dS d||dS # 1 sw Y   xY w)u   
    finish-task.sh의 goal_assertions 게이트 로직을 Python으로 미러링.

    Returns:
        dict with keys:
            - "result": "PASS" | "FAIL" | "BLOCKED" | "DISABLED"
            - "gate_mode": "warn" | "fail"
            - "commands_run": list of (cmd, exit_code)
    goal_assertionsDISABLED)result	gate_modecommands_runallowed_commandsrr   r   Nz'## goal_assertions.*?\n(.*?)(?=\n##|\Z)F   
z	`([^`]+)`r   T)shellcapture_outputtextfailBLOCKEDFAILPASS)r   r	   setr   getlistALLOWED_COMMANDSopenreadresearchSgroupstripsplit
subprocessrunappend
returncode)r   r%   allowed_cmdsfcontentmr&   	goal_failsection_textline	cmd_matchcmd
first_wordprocblockeds                  r   _run_goal_assertions_gaterN   F   s    ,-$=AR3Seghh/0I'(9:>>?QSWXhSijkL	ncG	4 &&( 			<grttLALIwwqz'') &&t, 	!D		,5I//!$**,CQJ->>44D doo 67!# 	'	!* v%#*i"(
 	
 9lSSO s   %FFreport_file_pathc                    t        d      sdddt        d      dS t        d      }t        d      j                  dd      }d}t        j
                  j                  |       rJt        | dd	      5 }|D ]-  }t        j                  d
|t        j                        s)|dz  }/ 	 ddd       ||kD  r|dk(  }|rdnd|||dS |dkD  rd|||dS d|||dS # 1 sw Y   1xY w)u  
    finish-task.sh의 unresolved_gate 로직을 Python으로 미러링.

    Returns:
        dict with keys:
            - "result": "PASS" | "WARN" | "BLOCKED" | "DISABLED"
            - "count": int
            - "max": int
            - "gate_mode": str
    unresolved_gater#   r   )r$   countmaxr%   max_in_scope_unresolved   r(   r   r   u)   범위 내 미해결|in.scope.*unresolvedr)   Nr.   r/   WARNr1   )r   r	   r   r3   ospathisfiler6   r8   r9   
IGNORECASE)rO   r%   max_unresolvedrR   rC   rH   rM   s          r   _run_unresolved_gater\      s    ,-$qWhIijj/0I%&78<<=VXYZNE	ww~~&'"C': 	a 99I4QSQ^Q^_QJE	
 ~v%#*i!"	
 	
 
 5V_``u^R[\\!	 	s   1+CCCc                   "    e Zd ZdZd Zd Zd Zy)%TestScenario1_L1SmoketestBlockPatternuS   BLOCK 패턴이 포함된 보고서는 l1_smoketest가 FAIL을 반환해야 한다.c                 j   |dz  dz  }|j                  d       d}|| dz  }|j                  dd	       t        |t        |            }|d
   }d}||k(  }|st	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }	t	        j                  d|       dz   d|	iz  }
t        t	        j                  |
            dx}x}}d |d   D        }t        |      }|st	        j                  d|d          dz   dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }	t        t	        j                  |	            dx}}y)u^   'UI 직접 확인 불가' 문자열이 포함된 보고서 파일이 있으면 status == FAIL.memoryreportsTparentsztest-scenario-1.mduM   # 작업 보고서

UI 직접 확인 불가

테스트 진행 불가 환경.
r   r   statusr0   ==z%(py1)s == %(py4)spy1py4uS   BLOCK 패턴 'UI 직접 확인 불가' 포함 시 FAIL 이어야 하지만 실제: 
>assert %(py6)spy6Nc              3   $   K   | ]  }d |v  
 yw)u   BLOCK 패턴N ).0ds     r   	<genexpr>z\TestScenario1_L1SmoketestBlockPattern.test_ui_block_pattern_triggers_fail.<locals>.<genexpr>   s     B1>Q&Bs   detailsu'   details에 BLOCK 패턴 언급 없음: .
>assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anypy0py2rk   )mkdirr   	l1_verifystr
@pytest_ar_call_reprcompare	_saferepr_format_assertmsgAssertionError_format_explanationru   @py_builtinslocals_should_repr_global_name)selftmp_pathreports_dirtask_idreport_filer$   @py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_assert1s               r   #test_ui_block_pattern_triggers_failzITestScenario1_L1SmoketestBlockPattern.test_ui_block_pattern_triggers_fail   s    )I5$'#!wisO3` 	 	

 7CM2h 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  bbhaij	
 	
 	
 	
 	
 Cy0AB 	
sBB 	
B 	
  6fY6G5HI	
 	
	6	
 	
   	
 	
 		  	
 	
 		 C 	
 	
 		 C 	
 	
 	
 	
 	
    c                 @   |dz  dz  }|j                  d       d}|| dz  }|j                  dd	       t        |t        |            }|d
   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}x}}dj                  |d         }d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }t	        j                  d|       dz   d|iz  }t        t	        j                  |            dx}}y)uD   details 필드에 매칭된 패턴 정보가 포함되어야 한다.r`   ra   Trb   ztest-scenario-1brd   u7   UI 직접 확인 불가 — 스크린샷 첨부 불가
r   r   re   r0   rf   rh   ri   assert %(py6)srm   N rs   u   UI 직접 확인 불가inz%(py1)s in %(py3)sdetails_combinedrj   py3u*   details에 패턴이 포함되어야 함: 
>assert %(py5)spy5)ry   r   rz   r{   r|   r}   r~   r   r   joinr   r   r   r   )r   r   r   r   r   r$   r   r   r   r   r   r   @py_format4@py_format6s                 r   test_block_pattern_in_detailszCTestScenario1_L1SmoketestBlockPattern.test_block_pattern_in_details   sp   )I5$'$!wisO3F 	 	

 7CM2h)6)6))))6))))))6)))))))88F9$56( 	
(,<< 	
 	
(,< 	
 	
 		 ) 	
 	
	6	
 	
  -= 	
 	
 		 -= 	
 	
  99I8JK	
 	
 	
 	
 	
r   c                 .   t        dt        |            }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)
uQ   보고서 파일이 없으면 SKIP을 반환해야 한다 (경계 조건 확인).znonexistent-task-9999re   SKIPrf   rh   ri   r   rm   N)rz   r{   r|   r}   r~   r   r   )r   r   r$   r   r   r   r   r   s           r    test_no_report_file_returns_skipzFTestScenario1_L1SmoketestBlockPattern.test_no_report_file_returns_skip   se    2CMBh)6)6))))6))))))6)))))))r   N)__name__
__module____qualname____doc__r   r   r   ro   r   r   r^   r^      s    ]
,
(*r   r^   c                   "    e Zd ZdZd Zd Zd Zy)TestScenario2_ImpactScannerWarnu_   수정된 A.py의 심볼을 B.py가 참조하고, B.py는 미수정이면 WARN이어야 한다.c                    |dz  }|dz  |j                  dd       j                  dd       t        t        |      dg      }|d   }d}||k(  }|st        j                  d	|fd
||f      t        j
                  |      t        j
                  |      dz  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}x}}|d   D 	cg c]  }	|	d   	 }
}	t        j                               fd|
D        }t        |      }|st        j                  d|
       dz   dt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |      t        j
                  |      dz  }t        t        j                  |            dx}}yc c}	w )uL   A.py 수정, B.py 미수정일 때 B.py에서 심볼 참조 감지 → WARN.A.pyB.pyul   def calculate_premium(base_rate, multiplier):
    """보험료 계산."""
    return base_rate * multiplier
r   r   zGfrom A import calculate_premium

monthly = calculate_premium(100, 1.5)
gate_resultrV   rf   rh   ri   u?   미수정 파일 참조 감지 시 WARN 이어야 함. 실제: rl   rm   Nunmodified_referencesfilec              3   D   K   | ]  }|v xs t              |v   y w)N)r{   )rp   rfb_pyb_py_abss     r   rr   zXTestScenario2_ImpactScannerWarn.test_unmodified_reference_causes_warn.<locals>.<genexpr>   s%     I8r>4SY"_4Is    u/   B.py가 unmodified_references에 없음. refs: rt   ru   rv   )r   r   r{   r|   r}   r~   r   r   r   resolveru   r   r   r   )r   r   a_pyr$   r   r   r   r   r   ref	ref_filesr   r   r   s               @@r   %test_unmodified_reference_causes_warnzETestScenario2_ImpactScannerWarn.test_unmodified_reference_causes_warn   s   & & 2 	 	 	
 	6 	 	
 c(mfX.m$ 	
 	
$. 	
 	
$ 	
 	
 		 % 	
 	
 		 )/ 	
 	
  NfUbNcMde	
 	
 	
 	
 	
 -33J,KLSS[L	Lt||~&IyI 	
sII 	
I 	
  >i[I	
 	
	6	
 	
   	
 	
 		  	
 	
 		 J 	
 	
 		 J 	
 	
 	
 	
 	
 Ms   ,Gc                    |dz  }|dz  }|j                  dd       |j                  dd       t        t        |      dg      }d}|d   }||v }|st        j                  d	|fd
||f      t        j
                  |      t        j
                  |      dz  }t        j                  d|d          dz   d|iz  }	t        t        j                  |	            dx}x}}y)uR   scan() 결과의 symbols_checked에 추출된 심볼명이 포함되어야 한다.r   r   z'def calculate_premium(x):
    return x
r   r   z from A import calculate_premium
calculate_premiumsymbols_checkedr   )z%(py1)s in %(py4)sri   u/   symbols_checked에 'calculate_premium' 없음: rl   rm   N	r   r   r{   r|   r}   r~   r   r   r   )
r   r   r   r   r$   r   r   r   r   r   s
             r   +test_symbols_checked_contains_function_namezKTestScenario2_ImpactScannerWarn.test_symbols_checked_contains_function_name  s    & & 7 	 	
 	/ 	 	

 c(mfX." 	
f->&? 	
"&?? 	
 	
"&? 	
 	
 		 # 	
 	
 		 '@ 	
 	
  >fEV>W=XY	
 	
 	
 	
 	
 	
r   c                    |dz  }|j                  dd       t        t        |      dg      }|d   }d}||k(  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }t        j                  d
|d          dz   d|iz  }t        t        j                  |            dx}x}}y)u:   미수정 파일에 참조가 없으면 PASS여야 한다.r   z2def unique_isolated_function_xyz():
    return 42
r   r   r   r1   rf   rh   ri   u-   참조 없으면 PASS 이어야 함. 실제: rl   rm   Nr   )	r   r   r   r$   r   r   r   r   r   s	            r   %test_no_unmodified_references_is_passzETestScenario2_ImpactScannerWarn.test_no_unmodified_references_is_pass  s    & B 	 	

 c(mfX.m$ 	
 	
$. 	
 	
$ 	
 	
 		 % 	
 	
 		 )/ 	
 	
  <F=<Q;RS	
 	
 	
 	
 	
 	
r   N)r   r   r   r   r   r   r   ro   r   r   r   r      s    i
:
(
r   r   c                   "    e Zd ZdZd Zd Zd Zy)TestScenario3_CIPreflightuw   항상 실패하는 pytest 테스트가 있는 디렉터리에 대해 ci_preflight.sh가 exit 1을 반환해야 한다.c                    |dz  j                  dd       |dz  j                  dd       t        j                  dt        t	        |      gddd	
      }|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  }t        j                  d|j
                   d|j                   d|j                         dz   d|iz  }t        t        j                   |            dx}x}}d}|j                  }||v }	|	st        j                  d|	fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|j                         dz   d|iz  }t        t        j                   |            dx}x}	}y)uX   test_always_fail.py가 존재하는 프로젝트에서 exit code 1, overall=FAIL 확인.zrequirements.txtzpytest
r   r   ztest_always_fail.pyuJ   def test_always_fail():
    assert False, '항상 실패하는 테스트'
bashT<   r,   r-   timeoutr)   rf   z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sr$   rw   rx   r   u3   pytest FAIL 시 exit code 1 이어야 함. 실제: 	
stdout: z	
stderr: 
>assert %(py7)spy7Nzoverall=FAILr   )z.%(py1)s in %(py5)s
{%(py5)s = %(py3)s.stdout
})rj   r   r   u!   stdout에 'overall=FAIL' 없음: )r   r>   r?   CI_PREFLIGHT_SCRIPTr{   rA   r|   r}   r   r   r   r~   r   stdoutstderrr   r   )
r   r   r$   r   @py_assert4r   r   @py_format8r   r   s
             r   !test_failing_pytest_causes_exit_1z;TestScenario3_CIPreflight.test_failing_pytest_causes_exit_1+  s#    
&	&22:2P	)	)55Z 	6 	

 (#h-8	
    	
A 	
 A% 	
 	
 A 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	 ! 	
 	
 
	 %& 	
 	
  B&BSBSAT U}}oZ@	
 	
 	
 	
 	
  	
 	
~. 	
 	
~ 	
 	
 		  	
 	
	6	
 	
  "( 	
 	
 		 "( 	
 	
 		 "/ 	
 	
  0?	
 	
 	
 	
 	
 	
r   c                 r   |dz  j                  dd       t        j                  dt        t	        |      gddd      }|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  }t        j                  d|j
                   d|j                         dz   d|iz  }t        t        j                  |            dx}x}}y)uu   테스트 파일이 없으면 pytest가 SKIP되고 overall=PASS 또는 No runners detected가 출력되어야 한다.zpyproject.tomlz[tool.pytest.ini_options]
r   r   r   Tr   r   r   rf   r   r$   r   u:   테스트 파일 없을 때 exit 0 이어야 함. 실제: r   r   r   N)r   r>   r?   r   r{   rA   r|   r}   r   r   r   r~   r   r   r   r   )r   r   r$   r   r   r   r   r   s           r   test_no_test_files_causes_passz8TestScenario3_CIPreflight.test_no_test_files_causes_passD  s8    
$	$00) 	1 	
 (#h-8	
    	
A 	
 A% 	
 	
 A 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	 ! 	
 	
 
	 %& 	
 	
  IIZIZH[ \}}o'	
 	
 	
 	
 	
 	
r   c                 6   t        |dz        }t        j                  dt        |gddd      }|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  }t        j                  d|j                         dz   d|iz  }t        t        j                  |            dx}x}}y)uX   존재하지 않는 디렉터리를 PROJECT_ROOT로 전달하면 exit 1이어야 한다.does_not_existr   T
   r   r)   rf   r   r$   r   uB   존재하지 않는 PROJECT_ROOT는 exit 1 이어야 함. 실제: r   r   N)r{   r>   r?   r   rA   r|   r}   r   r   r   r~   r   r   r   )	r   r   nonexistentr$   r   r   r   r   r   s	            r   !test_invalid_project_root_exits_1z;TestScenario3_CIPreflight.test_invalid_project_root_exits_1Y  s	   (%556(+6	
    	
A 	
 A% 	
 	
 A 	
 	
	6	
 	
   	
 	
 		  	
 	
 		 ! 	
 	
 		 %& 	
 	
  QQWQbQbPcd	
 	
 	
 	
 	
 	
r   N)r   r   r   r   r   r   r   ro   r   r   r   r   (  s     B
2
*
r   r   c                       e Zd ZdZd Zd Zy)#TestScenario4_GoalAssertionsAllPassuT   모든 goal_assertions 명령이 exit 0을 반환하면 GOAL-GATE PASS여야 한다.c                 <   |dz  }|j                  dt         dd       t        t        |            }|d   }d}||k(  }|st	        j
                  d|fd	||f      t	        j                  |      t	        j                  |      d
z  }t	        j                  d|       dz   d|iz  }t        t	        j                  |            dx}x}}|d   }	t        |	      }d}
||
k\  }|st	        j
                  d|fd||
f      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |	      t	        j                  |      t	        j                  |
      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}	x}x}}
|d   D ]  \  }}d}||k(  }	|	st	        j
                  d|	fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }t	        j                  d| d|       dz   d|iz  }t        t	        j                  |            dx}	} y) uD   grep으로 실제 존재하는 패턴을 검색 → exit 0 → PASS.task.mdz;# task-integration-4

## goal_assertions
- `grep -c "def " /scripts/impact_scanner.py`
r   r   r$   r1   rf   rh   ri   u8   모든 assertion 통과 시 PASS 이어야 함. 실제: rl   rm   Nr&   r)   >=z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} >= %(py7)slenrw   rx   rk   r   )   최소 1개 명령이 실행되어야 함
>assert %(py9)spy9r   z%(py0)s == %(py3)s	exit_coderw   r   u   명령 'u*   '의 exit code가 0이어야 함. 실제: r   r   r   WORKSPACE_ROOTrN   r{   r|   r}   r~   r   r   r   r   r   r   r   )r   r   	task_filer$   r   r   r   r   r   r   @py_assert6@py_assert5r   @py_format10rJ   r   r   r   s                     r   *test_all_passing_assertions_result_in_passzNTestScenario4_GoalAssertionsAllPass.test_all_passing_assertions_result_in_passp  s   y(	##1"22OQ 	 	 	
 +3y>:h 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  GvhO	
 	
 	
 	
 	
 .)\s)*\a\*a/\\\*a\\\\\\s\\\s\\\)\\\*\\\a\\\1\\\\\\\\$^4 	iNC !h9>hhh9hhhhhh9hhh9hhhhhhXcU2\]f\g#hhhhhhh	ir   c                    |dz  }|j                  dt         dd       t        t        |            }|d   }d}||k(  }|st	        j
                  d|fd	||f      t	        j                  |      t	        j                  |      d
z  }t	        j                  d|       dz   d|iz  }t        t	        j                  |            dx}x}}|d   }	t        |	      }d}
||
k(  }|st	        j
                  d|fd||
f      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |	      t	        j                  |      t	        j                  |
      dz  }t	        j                  dt        |d                dz   d|iz  }t        t	        j                  |            dx}	x}x}}
y)u4   여러 assertion 명령이 모두 통과하면 PASS.r   z<# task-integration-4b

## goal_assertions
- `grep -c "def " zE/scripts/impact_scanner.py`
- `python3 -c "import sys; sys.exit(0)"`
r   r   r$   r1   rf   rh   ri   u   모두 통과하면 PASS: rl   rm   Nr&      )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   r   u,   2개 명령이 실행되어야 함. 실제: r   r   r   )r   r   r   r$   r   r   r   r   r   r   r   r   r   r   s                 r   )test_multiple_passing_assertions_all_passzMTestScenario4_GoalAssertionsAllPass.test_multiple_passing_assertions_all_pass  s   y(	##1"2 3;<  	 	
 +3y>:hP6P6)PPP6PPPPPP6PPP-Gx+PPPPPPPP.) 	
s)* 	
a 	
*a/ 	
 	
*a 	
 	
	6	
 	
   	
 	
 		  	
 	
 		 * 	
 	
 		 + 	
 	
 		 /0 	
 	
  ;3vn?U;V:WX	
 	
 	
 	
 	
 	
r   N)r   r   r   r   r   r   ro   r   r   r   r   m  s    ^i(
r   r   c                       e Zd ZdZd Zd Zy) TestScenario5_GoalAssertionsFailuS   mode=fail 상태에서 goal_assertions가 실패하면 BLOCKED 반환해야 한다.c                 2   |dz  }|j                  dt         dd       t        d      }d}||k(  }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}}t        t        |            }|d   }	d}
|	|
k(  }|st        j                  d|fd|	|
f      t        j                  |	      t        j                  |
      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}	x}}
y)uL   존재하지 않는 패턴을 grep → exit non-0 → mode=fail → BLOCKED.r   zQ# task-integration-5

## goal_assertions
- `grep -c "NONEXISTENT_PATTERN_xyz123" r   r   r   r"   r.   rf   r   moder   u3   이 시나리오는 mode=fail 전제. 실제 mode: r   r   Nr$   r/   rh   ri   u@   mode=fail + assertion 실패 → BLOCKED 이어야 함. 실제: rl   rm   )r   r   r	   r|   r}   r   r   r   r~   r   r   r   rN   r{   )r   r   r   r   r   r   r   r   r$   r   r   r   r   s                r    test_failing_grep_causes_blockedzATestScenario5_GoalAssertionsFail.test_failing_grep_causes_blocked  s   y(	99G8HHeg 	 	 	
 ./ 	
tv~ 	
 	
tv 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
  B$H	
 	
 	
 	
 	
 +3y>:h 	
9 	
9, 	
 	
9 	
 	
 		   	
 	
 		 $- 	
 	
  OvhW	
 	
 	
 	
 	
 	
r   c                    |dz  }|j                  dt         dd       t        t        |            }|d   }t	        |      }d}||k\  }|st        j                  d|fd	||f      d
t        j                         v st        j                  t              rt        j                  t              nd
t        j                  |      t        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }	t        t        j                  |	            dx}x}x}}|d   D 
cg c]  \  }
}|dk7  s|
|f }}
}t	        |      }d}||k\  }|st        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  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}x}}yc c}}
w )u:   실패한 명령의 exit_code가 0이 아니어야 한다.r   zR# task-integration-5b

## goal_assertions
- `grep -c "NONEXISTENT_PATTERN_xyz123" r   r   r   r&   r)   r   r   r   r   r   r   r   Nr   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sfailing_cmdsrw   rj   r   rm   u=   실패한 명령이 최소 1개 있어야 함. commands_run: 
>assert %(py8)spy8)r   r   rN   r{   r   r|   r}   r   r   r   r~   r   r   r   )r   r   r   r$   r   r   r   r   r   r   rJ   ecr   r   r   r   @py_format9s                    r   (test_failing_assertion_exit_code_nonzerozITestScenario5_GoalAssertionsFail.test_failing_assertion_exit_code_nonzero  s   y(	99G8HHeg 	 	 	
 +3y>:.)\s)*\a\*a/\\\*a\\\\\\s\\\s\\\)\\\*\\\a\\\1\\\\\\\\171GSgc22QR7b	SS<  	
A 	
 A% 	
 	
 	
 A 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
    	
 	
 		   	
 	
 		 ! 	
 	
 		 %& 	
 	
  LFSaLbKcd	
 	
 	
 	
 	
 	
 Ts   =JJN)r   r   r   r   r   r   ro   r   r   r   r     s    ]
,
r   r   c                   "    e Zd ZdZd Zd Zd Zy)!TestScenario6_UnresolvedGateBlockuJ   max_in_scope_unresolved=3인데 count=4이면 BLOCKED 반환해야 한다.c                    t        d      j                  dd      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       d	z   d
|iz  }t        t        j                  |            dx}}|dz  }|j                  dd       t        t              j                  d      }	 t        j                   |      }	d|	d   d   d<   t        t              j                  t        j"                  |	dd      d       t%        t'        |            }
t        t              j                  |d       |
d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|
       dz   d|iz  }t        t        j                  |            dx}x}}|
d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|
d          dz   d|iz  }t        t        j                  |            dx}x}}y# t        t              j                  |d       w xY w) u>   '범위 내 미해결' 4줄 → count(4) > max(3) → BLOCKED.rQ   rT   rU   rf   r   max_valr   u.   이 시나리오는 max=3 전제. 실제 max: r   r   N	report.mdu   # 보고서

- 범위 내 미해결: 이슈 A
- 범위 내 미해결: 이슈 B
- 범위 내 미해결: 이슈 C
- 범위 내 미해결: 이슈 D
r   r   r.   gatesr   r   Findentensure_asciir$   r/   rh   ri   u?   count=4 > max=3 + mode=fail → BLOCKED 이어야 함. 실제: rl   rm   rR      u   count는 4여야 함. 실제: )r   r3   r|   r}   r   r   r   r~   r   r   r   r   r   r   r   jsonloadsdumpsr\   r{   )r   r   r  r   r   r   r   r   original_configconfig_datar$   r   r   r   r   s                  r   .test_four_unresolved_exceed_max_causes_blockedzPTestScenario6_UnresolvedGateBlock.test_four_unresolved_exceed_max_causes_blocked  s[    ##4599:SUVWWw!|WWWw!WWWWWWwWWWwWWW!WWWMgYWWWWWWW,1
  	 	
 /0::G:L		Q**_5K>DK !23F;!"--

;quEPW .  *#k*:;F!"--o-Ph 	
9 	
9, 	
 	
9 	
 	
 		   	
 	
 		 $- 	
 	
  NfXV	
 	
 	
 	
 	
 gW!W!#WWW!WWWWWW!WWW'EfWoEV%WWWWWWWW !"--o-Ps   A*K "K5c                    |dz  }|j                  dd       t        t        |            }|d   }d}||k7  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }t        j                  d
|       dz   d|iz  }t        t        j                  |            dx}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }dd|iz  }t        t        j                  |            dx}x}}y)uP   '범위 내 미해결' 정확히 3줄 → count == max → WARN (초과 아님).r  up   # 보고서

- 범위 내 미해결: 이슈 A
- 범위 내 미해결: 이슈 B
- 범위 내 미해결: 이슈 C
r   r   r$   r/   !=z%(py1)s != %(py4)sri   uK   count=3 == max=3은 초과가 아님 → BLOCKED 아니어야 함. 실제: rl   rm   NrR   rU   rf   rh   r   	r   r\   r{   r|   r}   r~   r   r   r   	r   r   r   r$   r   r   r   r   r   s	            r   0test_three_unresolved_within_max_is_warn_or_passzRTestScenario6_UnresolvedGateBlock.test_three_unresolved_within_max_is_warn_or_pass  s   ,1  	 	
 &c+&67 h 	
9 	
9, 	
 	
9 	
 	
 		   	
 	
 		 $- 	
 	
  ZZ`Yab	
 	
 	
 	
 	
 g#!#!####!######!#######r   c                    |dz  }|j                  dd       t        t        |            }|d   }d}||k(  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }t        j                  d
|       dz   d|iz  }t        t        j                  |            dx}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }dd|iz  }t        t        j                  |            dx}x}}y)u    미해결 이슈 없으면 PASS.r  u&   # 보고서

모든 이슈 해결됨.
r   r   r$   r1   rf   rh   ri   u   미해결 없으면 PASS: rl   rm   NrR   r   r   r  r  s	            r   test_zero_unresolved_is_passz>TestScenario6_UnresolvedGateBlock.test_zero_unresolved_is_pass  s    ,JU\]%c+&67hP6P6)PPP6PPPPPP6PPP-Gx+PPPPPPPPg#!#!####!######!#######r   N)r   r   r   r   r  r  r  ro   r   r   r  r    s    T XD$&$r   r  c                       e Zd ZdZej
                  j                  d      d        Zej
                  j                  d      d        Zy)TestScenario7_WarnModeNoBlockuk   goal_assertions mode=warn이면 assertion 실패 시 BLOCKED가 아닌 FAIL(경고)만 반환해야 한다.r   c                    t        j                  t        t              j	                  d            }d|d   d   d<   t        t              j                  t        j                  |dd	      d       |d
z  }|j                  dt         dd       t        t        |            }|d   }d}||k7  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            dx}x}}|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            dx}x}}|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d          dz   d|iz  }	t        t        j                  |	            dx}x}}y)u   
        gate-config.json goal_assertions mode를 warn으로 변경 후
        failing assertion 실행 → BLOCKED가 아닌 FAIL (경고) 반환.
        gate_config_backup 픽스처가 테스트 후 원본 자동 복원 보장.
        r   r   warnr  r"   r   r   Fr  r   zQ# task-integration-7

## goal_assertions
- `grep -c "NONEXISTENT_PATTERN_xyz123" r   r$   r/   r  r  ri   uC   mode=warn + assertion 실패 → BLOCKED 아니어야 함. 실제: rl   rm   Nr0   rf   rh   uM   mode=warn + assertion 실패 → FAIL 이어야 함 (블록 없음). 실제: r%   u)   gate_mode가 warn 이어야 함. 실제: )r  r  r   r   r   r   r  r   rN   r{   r|   r}   r~   r   r   r   )
r   r   r  r   r$   r   r   r   r   r   s
             r   )test_warn_mode_failing_assertion_no_blockzGTestScenario7_WarnModeNoBlock.test_warn_mode_failing_assertion_no_block  so    jj&6!7!A!A7!A!ST:@G./7))JJ{15AG 	* 	
 y(	99G8HHeg 	 	 	
 +3y>: h 	
9 	
9, 	
 	
9 	
 	
 		   	
 	
 		 $- 	
 	
  RRXQYZ	
 	
 	
 	
 	
 h 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  \\b[cd	
 	
 	
 	
 	
 k" 	
f 	
"f, 	
 	
"f 	
 	
 		 # 	
 	
 		 '- 	
 	
  8{8K7LM	
 	
 	
 	
 	
 	
r   c                 ~   t        j                  t        t              j	                  d            }d|d   d   d<   t        t              j                  t        j                  |dd	      d       t        d      }d}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                   |            dx}}y)u   
        gate_config_backup 픽스처 동작 검증 — 테스트 후 원본 mode=fail 복원 확인.
        이 테스트는 gate_config_backup을 사용하여 설정을 변경 후 픽스처가 복원하는지 확인.
        r   r   r  r  r"   r   r   Fr  rf   r   changed_moder   u/   변경 후 mode는 warn 이어야 함. 실제: r   r   N)r  r  r   r   r   r   r  r	   r|   r}   r   r   r   r~   r   r   r   )r   r  r   r   r   r   r   s          r   )test_gate_config_restored_after_scenario7zGTestScenario7_WarnModeNoBlock.test_gate_config_restored_after_scenario78  s     jj&6!7!A!A7!A!ST:@G./7))JJ{15AG 	* 	

 %%67%g|v%ggg|vgggggg|ggg|gggvggg)XYeXf'gggggggr   N)	r   r   r   r   r   markusefixturesr  r!  ro   r   r   r  r    sN    u[[12 
 3 
D [[12h 3hr   r  c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)%TestScenario8_AutoInjectAffectedFilesuh   FeatureGate 백틱 토큰이 있는 task_desc에 affected_files 섹션이 자동 주입되어야 한다.c                    d}t        |t              }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}y
)ui   `FeatureGate` 토큰 → grep → 2개 이상 파일 → ## affected_files (auto-detected) 섹션 생성.uH   다음 클래스를 확인하세요: `FeatureGate` 관련 변경 사항.!## affected_files (auto-detected)r   r   r$   r   u>   '## affected_files (auto-detected)' 섹션이 없음.
결과:
r   r   Nr   r   r|   r}   r~   r   r   r   r   r   r   r   	task_descr$   r   r   r   r   s          r   5test_backtick_token_triggers_affected_files_injectionz[TestScenario8_AutoInjectAffectedFiles.test_backtick_token_triggers_affected_files_injectionT  s    ^	,YG2 	
2f< 	
 	
2f 	
 	
 		 3 	
 	
	6	
 	
  7= 	
 	
 		 7= 	
 	
  OvhW	
 	
 	
 	
 	
r   c                    d}t        |t              }t        j                  d|t        j                        }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       d	z   d
|iz  }t        t        j                  |            dx}}|j                  d      j                         }|j!                  d      D 	cg c]  }	|	j#                  d      s|	 }
}	t%        |
      }d}||k\  }|st        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  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}}yc c}	w )u{   FeatureGate는 tests/test_dispatch_auto_inject.py와 scripts/tests/test_impact_scanner.py에 존재 — 2개 이상 감지.u+   클래스 `FeatureGate`를 수정하세요.z5## affected_files \(auto-detected\)\n(.*?)(?=\n##|\Z)N)is not)z%(py0)s is not %(py3)ssection_matchr   u   affected_files 섹션 없음:
r   r   r)   r*   z- r   r   r   r   
file_linesr   u=   최소 2개 파일이 감지되어야 함. 감지된 파일:
r   r   )r   r   r8   r9   r:   r|   r}   r   r   r   r~   r   r   r   r;   r<   r=   
startswithr   )r   r*  r$   r.  r   r   r   r   files_sectionrH   r/  r   r   r   r   s                  r    test_at_least_two_files_detectedzFTestScenario8_AutoInjectAffectedFiles.test_at_least_two_files_detected^  s   A	,YG 		DDD

 %)T}D(TTT}DTTTTTT}TTT}TTTDTTT,KF8*TTTTTTT%++A.446'4':':4'@ZtDOOTXDYdZ
Z: 	
! 	
!# 	
 	
 	
! 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 #$ 	
 	
  M]O\	
 	
 	
 	
 	
 	
 [s   (I0?I0c                 P   d}t        |t              }g }d}||v }|}|sd}||v }|}|sqt        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }	dd	|	iz  }
|j                  |
       |st        j                  dfd
|f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }|j                  |       t        j                  |d      i z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}x}x}}y)ur   알려진 참조 파일(test_dispatch_auto_inject.py, test_impact_scanner.py)이 목록에 포함되어야 한다.u+   클래스 `FeatureGate`를 분석하세요.ztest_dispatch_auto_inject.pyztest_impact_scanner.pyr   )z%(py3)s in %(py5)sr$   )r   r   z%(py7)sr   )z%(py10)s in %(py12)s)py10py12z%(py14)spy14r)   uI   알려진 FeatureGate 참조 파일이 affected_files에 없음.
결과:
z
>assert %(py17)spy17N)r   r   r|   r}   r~   r   r   r   r@   _format_boolopr   r   r   )r   r*  r$   r   r   r   r   @py_assert9@py_assert11r   r   @py_format13@py_format15@py_format16@py_format18s                  r   !test_known_files_in_affected_listzGTestScenario8_AutoInjectAffectedFiles.test_known_files_in_affected_listr  s   A	,YG	
- 	
-7 	
;S 	
;SW];] 	
 	
 	
- 	
 	
 		 . 	
 	
	6	
 	
  28 	
 	
 		 28 	
 	
 	
	6	
		
 	
;SW] 	
 	
 		 <T 	
 	
	6	
 	
  X^ 	
 	
 		 X^ 	
 	
 	
	6	
		
 	
 	
  ZZ`Yab	
 	
 	
 	
 	
 	
r   c                    d}t        |t              }d}||v}|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d
x}}y
)uR   이미 ## affected_files 섹션이 있으면 중복 주입하지 않아야 한다.uU   클래스 `FeatureGate`를 수정하세요.

## affected_files
- src/feature_gate.py
r'  )not in)z%(py1)s not in %(py3)sr$   r   uK   이미 affected_files 있으면 auto-detected 섹션 추가 없어야 함:
r   r   Nz## affected_filesr   r   zassert %(py5)sr(  r)  s          r   &test_no_injection_when_already_presentzLTestScenario8_AutoInjectAffectedFiles.test_no_injection_when_already_present|  s#   & 	 -YG 3 	
2&@ 	
 	
2& 	
 	
 		 3 	
 	
	6	
 	
  ;A 	
 	
 		 ;A 	
 	
  [[aZbc	
 	
 	
 	
 	
 #,"f,,,,"f,,,",,,,,,f,,,f,,,,,,,r   c                    d}t        |t              }t        |t              }|s!t	        j
                  d      dz   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dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      dz  }t        t	        j                  |            d}y)	uh   COMMON_FILTER에 해당하는 토큰(예: `data`, `config`)은 grep 대상에서 제외되어야 한다.u-   다음 `data`와 `config`를 확인하세요.u#   반환값은 문자열이어야 함z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancer$   r{   )rw   rj   rx   rk   N)r   r   rD  r{   r|   r   r   r   r   r~   r   r   )r   r*  r$   r   r   s        r   &test_common_filter_tokens_not_injectedzLTestScenario8_AutoInjectAffectedFiles.test_common_filter_tokens_not_injected  s     D	 -YG&#&M&MM(MMMMMMMzMMMz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Mr   N)	r   r   r   r   r+  r2  r?  rB  rE  ro   r   r   r%  r%  Q  s    r

(
-"	Nr   r%  c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)TestGateConfigConsistencyu]   gate-config.json 설정이 기대값과 일치하는지 확인하는 회귀 방지 테스트.c                    g d}|D ]  }t        |      }|st        j                  d| d      dz   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z  }t        t        j                  |            d} y)	u^   impact_scanner, ci_preflight, l1_smoketest, goal_assertions, unresolved_gate 모두 활성화.)impact_scannerci_preflightl1_smoketestr"   rQ   u   게이트 'u   '가 비활성화 상태z.
>assert %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}r   gate)rw   rj   r   N)	r   r|   r   r   r   r   r~   r   r   )r   required_gatesrL  r   r   s        r   test_all_required_gates_enabledz9TestGateConfigConsistency.test_all_required_gates_enabled  s    
 # 	WD"4(V(VVKv=U*VVVVVVV?VVV?VVVVVV4VVV4VVV(VVVVVV	Wr   c                    t        d      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}y
)u6   goal_assertions 기본 mode는 'fail'이어야 한다.r"   r.   rf   r   r   r   u4   goal_assertions mode는 fail 이어야 함. 실제: r   r   N
r	   r|   r}   r   r   r   r~   r   r   r   r   r   r   r   r   r   s         r   !test_goal_assertions_mode_is_failz;TestGateConfigConsistency.test_goal_assertions_mode_is_fail  sw    ./\tv~\\\tv\\\\\\t\\\t\\\v\\\!UVZU[\\\\\\\r   c                    t        d      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
x}}y
)u3   l1_smoketest 기본 mode는 'fail'이어야 한다.rK  r.   rf   r   r   r   u1   l1_smoketest mode는 fail 이어야 함. 실제: r   r   NrP  rQ  s         r   test_l1_smoketest_mode_is_failz8TestGateConfigConsistency.test_l1_smoketest_mode_is_fail  sv    ^,Ytv~YYYtvYYYYYYtYYYtYYYvYYY!RSWRXYYYYYYYr   c                 H   t        d      }|j                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        j                  d|       d	z   d
|iz  }t        t        j                  |            dx}x}x}x}}y)u@   unresolved_gate의 max_in_scope_unresolved는 3이어야 한다.rQ   rT   rU   rf   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)scfg)rw   rx   rk   rm   r   u3   max_in_scope_unresolved는 3이어야 함. 실제: z
>assert %(py11)spy11N)r   r3   r|   r}   r   r   r   r~   r   r   r   )	r   rV  r   r   r   @py_assert8@py_assert7r   @py_format12s	            r   !test_unresolved_gate_max_is_threez;TestGateConfigConsistency.test_unresolved_gate_max_is_three  s   01ww 	
0 	
w01 	
Q 	
1Q6 	
 	
1Q 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 1 	
 	
 		 2 	
 	
 		 67 	
 	
  B#G	
 	
 	
 	
 	
 	
r   c                 l   t        d      }t        |j                  dg             }h d}||z
  }| }|s~t        j                  d|       dz   ddt        j                         v st        j                  |      rt        j                  |      ndiz  }t        t        j                  |            d}y)	uO   goal_assertions allowed_commands에 핵심 명령어가 포함되어야 한다.r"   r'   >   r   r   r   r   u#   allowed_commands에 없는 명령: z
>assert not %(py0)srw   missingN)r   r2   r3   r|   r   r   r   r   r~   r   r   )r   rV  allowedexpectedr]  r   @py_format2s          r   /test_goal_assertions_allowed_commands_whitelistzITestGateConfigConsistency.test_goal_assertions_allowed_commands_whitelist  s}    01cgg0"568W${K{KKA'KKKKKKK7KKK7KKKKKKr   N)	r   r   r   r   rN  rR  rT  r[  ra  ro   r   r   rG  rG    s"    g
W]
Z

Lr   rG  )0r   builtinsr   _pytest.assertion.rewrite	assertionrewriter|   r  rW   r8   r>   syspathlibr   r   r   rX   insertrI  r   l1_smoketest_checkr   rz   dispatchr   utils.gate_config_loaderr   r   r	   r   r   r   r5   fixturer   r{   dictrN   r\   r^   r   r   r   r   r  r  r%  rG  ro   r   r   <module>rn     s     	 	  
  
 '!HHOOA~& 0HHOOA45/sxx?HHOOACD
   2 0 U U
 77<<:LM ggll>9>OP Z  J J7Tc 7Td 7Tt#]3 #]4 #]T0* 0*n@
 @
N>
 >
J'
 '
\)
 )
`@$ @$N5h 5h~EN ENX&L &Lr   