
    0jy                    &   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
Z
ddlZddlZddlZddlmZ  ee      j%                         j&                  d   Z ee      ej,                  vr"ej,                  j/                  d ee             ddlmZ edz  dz  Zej8                  j;                  d      Ze eedd	      xs d	 ee      k7  r e ej8                        D  cg c]  } | dk(  s| jC                  d
      s|  c} D ]  Z"ej8                  e"=   ejF                  de eedz        g      Z$g Z%dZ&e$e&uZ'e'Z(e're$jR                  Z*dZ+e*e+uZ,e,Z(e(sB ejZ                  de'fde$e&f      d ej\                         v s ej^                  e$      r ej`                  e$      nd ej`                  e&      dz  Z1dde1iz  Z2e%jg                  e2       e'r ejZ                  de,fde*e+f      d ej\                         v s ej^                  e$      r ej`                  e$      nd ej`                  e*       ej`                  e+      dz  Z4dde4iz  Z5e%jg                  e5        ejl                  e%d      i z  Z7dde7iz  Z8 e9 ejt                  e8            dxZ(xZ%xZ'xZ&xZ*xZ,Z+ ejv                  e$      Z<e<ej8                  d<   e$jR                  j{                  e<       ddl>m?Z@ ddl>mAZB ddl>mCZD dZEdZFdZGdJdZHeEeFdd ZIdKd!ZJdLd"ZKdMdLd#ZLdNd$ZMdOdPd%ZNd& ZOdQdRd'ZPdSdRd(ZQd) ZRdTd*ZSd+ ZTd, ZUd- ZVd. ZWd/ ZXd0 ZYd1 ZZd2 Z[d3 Z\d4 Z]d5 Z^d6 Z_d7 Z`d8 Zad9 Zbd: Zcd; Zdd< Zed= Zfd> Zgd? Zhd@ ZidA ZjdB ZkdC ZldD ZmdE ZndF ZodG ZpdH ZqdI Zryc c} w )UuU  task-2753 Option B provenance-path — regression (16).

대상 모듈:
- dispatch.anu_executor_provenance (validate_executor_provenance + ProvenanceResult + REASON_*)
- dispatch.anu_pickup_driver (process_one provenance-path 분기 + provenance_path_enabled flag)
- dispatch.anu_collector_result (CollectorResult.adopted_via)

design packet §5 test plan 매핑(번호는 packet §5 기준):
  (A) 순수함수 단위테스트 — validate_executor_provenance 직접 호출 (조건 1,3~13,15)
  (B) process_one 통합테스트 — driver 분기 (조건 2,14,16)

절대 제약:
- 실제 ANU 키 literal('c119085...') 0건. raw key 테스트는 가짜 키 sentinel 사용.
- pickup_once 실호출 0 — 전부 mock 주입(pickup_fn/verify_fn/provenance_fn/collector_writer_fn).
  실제 wake/cron/callback fire 0.
- tmp_path fixture 만 사용. 실제 memory 디렉토리에 쓰지 않는다.

기존 패턴(test_anu_pickup_driver_2721.py)의 sys.path/dispatch import 보강 헤더,
_make_dirs/_events_dir/_write_result/_enable_activation/_age/_NO_SLEEP/make_pickup_mock 를
그대로 재사용/모방한다.
    )annotationsN)Path   dispatchz__init__.py__file__ z	dispatch.)submodule_search_locationsis not)z%(py2)s is not %(py5)s_spec)py2py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16zassert %(py19)spy19)anu_pickup_driver)anu_executor_provenance)anu_collector_result	task-2753@deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef FAKE_RAW_KEY_SENTINEL_DO_NOT_USEc                 "    t         ddt        ddS )u]   provenance-path 통과용 valid executor_result (envelope 없음 = provenance 진입 조건).EXECUTOR_RESULT_WRITTENPASSz	report.md)task_idcompletion_signalterminal_statuscapsule_sha256report_path)TASK_IDCAPSULE_SHA     A/home/jay/workspace/tests/regression/test_provenance_path_2753.py_valid_resultr(   J   s     6!%" r&   r   source_sha256c                      fdS )u~   capability_reader mock: capability_reader(task_id)->dict|None.
    snapshot dict = {"task_id", "source_sha256"} 최소 필드.c                    dS )Nr)   r%   )tidr*   r   s    r'   <lambda>z_cap_reader.<locals>.<lambda>Z   s    7]K r&   r%   r)   s   ``r'   _cap_readerr/   W   s     LKr&   c                    | dz  dz  dz  j                  dd       | dz  dz  j                  dd       | dz  dz  j                  dd       | S )uO   tmp_path 안에 inbox/state/capabilities 디렉토리를 만들고 root 반환.memoryevents	p0b_inboxTparentsexist_okstatecapabilities)mkdir)tmp_paths    r'   
_make_dirsr;   `   sd    8#k188PT8U7"))$)F>)000MOr&   c                    | dz  dz  dz  S )Nr1   r2   r3   r%   roots    r'   _events_dirr?   h   s    (?X%33r&   c                    |	t          d}|
t               }t        |       |z  }|j                  t	        j
                  |      d       |S )u   inbox(memory/events/p0b_inbox) 아래에 <task_id>.result.json 을 쓰고 경로 반환.
    조건4/조건8 의 source-path/sha 계산이 실제 파일을 요구하므로 정규 경로에 쓴다..result.jsonutf-8encoding)r#   r(   r?   
write_textjsondumps)r>   namepayloadps       r'   _write_resultrK   l   sN     |,'/DD ALLG$wL7Hr&   c                    | dz  dz  dz  }|j                   j                  dd       |j                  t        j                  dz   d       y )	Nr1   r7   p0b_driver_enabledTr4   
rB   rC   )parentr9   rE   drvACTIVATION_ENABLED)r>   flags     r'   _enable_activationrS   x   sH    (?W$';;DKKdT2OOC**T1GODr&   c                t    t        j                         |z
  }t        j                  t	        |       ||f       y)uU   result 파일 mtime/atime 을 과거로 설정 — readiness 'aged' 게이트 통과.N)_timetimeosutimestr)pathsecondspasts      r'   _ager]   ~   s(    ::<'!DHHSYt%r&   c                      y Nr%   )aks     r'   r.   r.          r&   c                (     g  fd}|_         |S )u   pickup_fn mock — provenance-path 는 pickup_fn 을 호출하지 않아야 하므로,
    이 mock 의 calls 가 비어있는지 검증하는 데 사용한다.c                 n    j                  | |f       t        j                  dk(  dgt        g       S )N
WAKE_BUILTx)verdictokargvr   reasons)appendtypesSimpleNamespacer#   argskwargscallsrg   s     r'   _pickupz!make_pickup_mock.<locals>._pickup   s9    dF^$$$L!8
 	
r&   rq   )rg   rr   rq   s   ` @r'   make_pickup_mockrt      s     E
 GMNr&   c                (     g  fd}|_         |S )u9   verify_fn mock (기존 envelope 경로 진입 검증용).c                 d    j                  | |f       t        j                  dk(  i dg       S )NAUTHORITATIVEr   )rg   rh   owner_resolutionclassificationrj   rk   rl   rm   rn   s     r'   _verifyz!make_verify_mock.<locals>._verify   s7    dF^$$$O!;B
 	
r&   rs   )rg   r{   rq   s   ` @r'   make_verify_mockr|      s    E
 GMNr&   c                 $    g fd} | _         | S )uV   launcher_fn/callback fire mock — provenance-path 에서 fire 0(미호출)을 검증.c                 V    j                  | |f       t        j                  d      S )NLAUNCHED)decisionrz   )ro   rp   rq   s     r'   _launchz#make_launcher_mock.<locals>._launch   s$    dF^$$$j99r&   rs   )r   rq   s    @r'   make_launcher_mockr      s    E: GMNr&   c                (     g  fd}|_         |S )u   provenance_fn spy — 호출 인자 기록 + ProvenanceResult 반환.
    integration 테스트(#14/#16)에서 '미호출' 검증, #2 에서 pass 주입에 사용.c                    j                  | ||f       rt        j                  dd      S t        j                  dd      S )NT	spysha123)rh   source_result_sha256Fspy_fail)rh   reason)rk   provProvenanceResult)resultresult_pathrp   rq   pass_results      r'   _fnz make_provenance_spy.<locals>._fn   s?    fk623((D{SS$$jAAr&   rs   )r   r   rq   s   ` @r'   make_provenance_spyr      s     EB CIJr&   c                 $    g fd} | _         | S )u<   collector_writer_fn spy — (collector, path) 인자 기록.c                .    j                  | |f       |S r_   )rk   )	collectorrZ   rq   s     r'   _writerz*make_collector_writer_spy.<locals>._writer   s    i&'r&   rs   )r   rq   s    @r'   make_collector_writer_spyr      s    E GMNr&   c                6
   t        |       }t        |      }t        j                  t	               t        |      t        |      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}}|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}||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&                  }|syddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }	t        t        j                  |	            d }dd l}
|
j+                  |j-                               j/                         }|j&                  }||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      nd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 )Nr>   capability_readerTisz*%(py2)s
{%(py2)s = %(py0)s.ok
} is %(py5)spvpy0r   r   assert %(py7)sr   r   ==)z.%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py5)sFz,%(py2)s
{%(py2)s = %(py0)s.skip
} is %(py5)sz1%(py2)s
{%(py2)s = %(py0)s.duplicate
} is %(py5)s8assert %(py2)s
{%(py2)s = %(py0)s.source_result_sha256
}r   r   r   )z<%(py2)s
{%(py2)s = %(py0)s.source_result_sha256
} == %(py4)sexpectedr   r   py4assert %(py6)spy6)r;   rK   r   validate_executor_provenancer(   rY   r/   rh   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr   skip	duplicater   hashlibsha256
read_bytes	hexdigest)r:   r>   rJ   r   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_format3r   r   @py_format5@py_format7s                 r'   test_unit_valid_result_okr      s   hDdA		*	*Qc$i%-
B 55D5D=5D225D999?922977e7e7e227e<< 5 <5    <5      2   2   <   5       """""""""2"""2""""""""""~~alln-779H""."h...."h......2...2..."......h...h.......r&   c                d   t        |       }t        |      }t        j                  t	               t        |      t        |      d       }|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                  }t        j                   }	||	k(  }|st        j                  d
|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	y )Nc                     y r_   r%   )r-   s    r'   r.   z3test_unit_missing_dispatch_record.<locals>.<lambda>   rb   r&   r   Fr   r   r   r   r   r   r   )z]%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_NO_DISPATCH_RECORD
}r   r   r   r   r   assert %(py8)spy8)r;   rK   r   r   r(   rY   rh   r   r   r   r   r   r   r   r   r   REASON_NO_DISPATCH_RECORDr:   r>   rJ   r   r   r   r   r   r   @py_assert5r   @py_format9s               r'   !test_unit_missing_dispatch_recordr      s=   hDdA		*	*Qc$i*
B 55E5E>5E225E9966669666669666666626662666966666666666666666666r&   c                v   t        |       }t        |      }t        j                  t	               t        |      t        |      t        d            }|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                   }t        j"                  }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	y )Nz
task-OTHER)r   r   Fr   r   r   r   r   r   r   )z[%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_TASK_ID_MISMATCH
}r   r   r   r   )r;   rK   r   r   r(   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_TASK_ID_MISMATCHr   s               r'   test_unit_task_id_mismatchr      sB   hDdA		*	*Qc$i%l;
B 55E5E>5E225E9944449444449444444424442444944444444444444444444r&   c                v   t        |       }t        |      }t        j                  t	               t        |      t        |      t        d            }|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                   }t        j"                  }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	y )NMISMATCHED_SHA)r*   r   Fr   r   r   r   r   r   r   )z_%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_CAPSULE_SHA_MISMATCH
}r   r   r   r   )r;   rK   r   r   r(   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_CAPSULE_SHA_MISMATCHr   s               r'   test_unit_capsule_sha_mismatchr      sC   hDdA		*	*Qc$i%4DE
B 55E5E>5E225E9988889888889888888828882888988888888888888888888r&   c                   t        |       }|t         dz  }|j                  t        j                  t                     d       t        j                  t               t        |      t        |      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&                  }t        j(                  }	||	k(  }|st        j                  d|fd||	f      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                   |	      dz  }
dd|
iz  }t#        t        j$                  |            d x}x}}	y )NrA   rB   rC   r   Fr   r   r   r   r   r   r   )z^%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_SOURCE_PATH_INVALID
}r   r   r   r   )r;   r#   rE   rF   rG   r(   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_SOURCE_PATH_INVALID)r:   r>   outsider   r   r   r   r   r   r   r   r   s               r'   test_unit_source_path_invalidr   	  sd   hDy--Gtzz-/2WE		*	*WCI%-
B 55E5E>5E225E9977779777779777777727772777977777777777777777777r&   c                   t        |       }t               }|j                  d       t        ||      }t	        j
                  |t        |      t        |      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"                  }t        j$                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                   |            d x}x}}
y )Nr"   rI   r   Fr   r   r   r   r   r   r   )zV%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_SCHEMA_FAIL
}r   r   r   r   )r;   r(   poprK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_SCHEMA_FAILr:   r>   rI   rJ   r   r   r   r   r   r   r   r   r   s                r'   )test_unit_schema_fail_missing_report_pathr     sR   hDoGKKdG,A		*	*Qc$i%-
B 55E5E>5E225E99////9/////9///////2///2///9////////////////////r&   c                   t        |       }t               }d|d<   t        ||      }t        j                  |t        |      t        |      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                   }t        j"                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                  |            d x}x}}
y )NFAILr    r   r   Fr   r   r   r   r   r   r   )z[%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_TERMINAL_INVALID
}r   r   r   r   )r;   r(   rK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_TERMINAL_INVALIDr   s                r'   test_unit_terminal_invalidr   %  sQ   hDoG!'GdG,A		*	*Qc$i%-
B 55E5E>5E225E9944449444449444444424442444944444444444444444444r&   c                J   t        |       }t        |      }t        |d       t        j                         dz   }t        j                  t               t        |      t        |      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}||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(                  }t
        j*                  }
||
k(  }|st        j                  d|fd||
f      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                   |
      dz  }dd|iz  }t#        t        j$                  |            d x}x}}
y )N
   )r[   i'  )r>   r   activation_epochFr   r   r   r   r   r   Tr   r   )z_%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_PRE_ACTIVATION_EPOCH
}r   r   r   r   )r;   rK   r]   rU   rV   r   r   r(   rY   r/   rh   r   r   r   r   r   r   r   r   r   r   REASON_PRE_ACTIVATION_EPOCH)r:   r>   rJ   future_epochr   r   r   r   r   r   r   r   r   s                r'   test_unit_stale_epoch_skipr   3  s   hDdAB::<&(L		*	*Qc$i%-%
B
 55E5E>5E225E77d7d?7d227d9988889888889888888828882888988888888888888888888r&   c                   t        |       }t               }d|d<   t        ||      }t        j                  |t        |      t        |      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                   }t        j"                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                  |            d x}x}}
y )NTschedule_created_by_executorr   r   Fr   r   r   r   r   r   r   )zY%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_CALLBACK_CLAIM
}r   r   r   r   )r;   r(   rK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_CALLBACK_CLAIMr   s                r'   !test_unit_callback_schedule_claimr   C  sQ   hDoG.2G*+dG,A		*	*Qc$i%-
B 55E5E>5E225E9922229222229222222222222222922222222222222222222r&   c                   t        |       }t               }d|d<   t        ||      }t        j                  |t        |      t        |      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                   }t        j"                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                  |            d x}x}}
y )NTself_collectorr   r   Fr   r   r   r   r   r   r   )z_%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_SELF_COLLECTOR_CLAIM
}r   r   r   r   )r;   r(   rK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_SELF_COLLECTOR_CLAIMr   s                r'   test_unit_self_collector_claimr   Q  sQ   hDoG $GdG,A		*	*Qc$i%-
B 55E5E>5E225E9988889888889888888828882888988888888888888888888r&   c                   t        |       }t               }d|d<   t        ||      }t        j                  |t        |      t        |      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                   }t        j"                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                  |            d x}x}}
y )NTowner_key_proof_presentr   r   Fr   r   r   r   r   r   r   )zY%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_SELF_KEY_CLAIM
}r   r   r   r   )r;   r(   rK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_SELF_KEY_CLAIMr   s                r'   test_unit_self_key_claimr   _  sQ   hDoG)-G%&dG,A		*	*Qc$i%-
B 55E5E>5E225E9922229222229222222222222222922222222222222222222r&   c                   t        |       }t        |      }t        j                  t	               t        |      t        |      t               d       }|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
}||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"                  }t        j$                  }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	y )Nc                     y)NTr%   )r-   shas     r'   r.   z%test_unit_duplicate.<locals>.<lambda>s  rb   r&   )r>   r   ledger_readerFr   r   r   r   r   r   Tr   r   )zT%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_DUPLICATE
}r   r   r   r   )r;   rK   r   r   r(   rY   r/   rh   r   r   r   r   r   r   r   r   r   r   REASON_DUPLICATEr   s               r'   test_unit_duplicater   m  s   hDdA		*	*Qc$i%-+
B
 55E5E>5E225E<<4<4<422<499----9-----9-------2---2---9--------------------r&   c                
   t        |       }t               }t        |d<   t        ||      }t	        j
                  |t        |      t        |      t               t        f      }|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"                  }t        j$                  }
||
k(  }|st        j                  d|fd||
f      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                  |
      dz  }dd|iz  }t        t        j                   |            d x}x}}
t        |      }t	        j
                  t               t        |      t        |      t               t        f      }|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}}t'        j(                  |j                  |j"                  |j*                  |j,                  |j.                  d      }t        |v}|st        j                  d|fdt        |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dz  }dd|iz  }t        t        j                   |            d }d}||v}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                   |            d }y )Nleaked_fieldr   )r>   r   forbidden_key_literalsFr   r   r   r   r   r   r   )zR%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_RAW_KEY
}r   r   r   r   Tpv_ok)rh   r   r   r   r   )not in)z%(py0)s not in %(py2)sFAKE_RAW_KEYdumpedr   zassert %(py4)sr   c119085addb0f8b7forbidden_real)r;   r(   r   rK   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_RAW_KEYrF   rG   r   r   r   )r:   r>   rI   rJ   r   r   r   r   r   r   r   r   r   p2r   r   r   r   r  s                      r'   *test_unit_raw_key_quarantine_and_zero_leakr  |  s   hDoG*GNdG,A		*	*Qc$i%- ,
B
 55E5E>5E225E99++++9+++++9+++++++2+++2+++9++++++++++++++++++++ 
t	B--Rs4y%- ,E
 88t8t8t558tZZhh%,, % : :

 F
 v%%%%<v%%%%%%<%%%<%%%%%%v%%%v%%%%%%%,N''''>''''''>'''>''''''''''''''''r&   c                <   t        |       }t        |       t               }t               }t               }t	               }t        |      }t        |       t        j                  t        |      t        |      |||t        dt               |	      }|j                  }t        j                  }	||	k(  }
|
st        j                  d|
fd||	f      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&                  |	      dz  }dd	|iz  }t)        t        j*                  |            d x}x}
}	|j,                  }t        j.                  }	||	k(  }
|
st        j                  d|
fd
||	f      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&                  |	      dz  }dd	|iz  }t)        t        j*                  |            d x}x}
}	|j0                  }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}
}|j2                  }t5        |      }d}||k(  }|s
t        j                  d|fd||f      dt!        j"                         v st        j$                  t4              rt        j&                  t4              nddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      t        j&                  |      t        j&                  |      dz  }dd|iz  }t)        t        j*                  |            d x}x}x}}|j2                  d   \  }}|j6                  }t8        j:                  }	||	k(  }
|
st        j                  d|
fd||	f      dt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      dt!        j"                         v st        j$                  t8              rt        j&                  t8              ndt        j&                  |	      dz  }dd	|iz  }t)        t        j*                  |            d x}x}
}	|j<                  }|syddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      dz  }t)        t        j*                  |            d }|j>                  }|t@        k(  }
|
st        j                  d|
fd|t@        f      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d z  }d!d"|iz  }t)        t        j*                  |            d x}}
|j2                  }t5        |      }d}||k(  }|s
t        j                  d|fd||f      dt!        j"                         v st        j$                  t4              rt        j&                  t4              ndd#t!        j"                         v st        j$                  |      rt        j&                  |      nd#t        j&                  |      t        j&                  |      t        j&                  |      dz  }dd|iz  }t)        t        j*                  |            d x}x}x}}|j2                  }t5        |      }d}||k(  }|s
t        j                  d|fd||f      dt!        j"                         v st        j$                  t4              rt        j&                  t4              ndd$t!        j"                         v st        j$                  |      rt        j&                  |      nd$t        j&                  |      t        j&                  |      t        j&                  |      dz  }dd|iz  }t)        t        j*                  |            d x}x}x}}|j2                  }t5        |      }d}||k(  }|s
t        j                  d|fd||f      dt!        j"                         v st        j$                  t4              rt        j&                  t4              ndd%t!        j"                         v st        j$                  |      rt        j&                  |      nd%t        j&                  |      t        j&                  |      t        j&                  |      dz  }dd|iz  }t)        t        j*                  |            d x}x}x}}y )&NTr>   	pickup_fnlauncher_fncallback_launch_fnsleep_fnprovenance_path_enabledr   collector_writer_fnr   z_%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py6)s
{%(py6)s = %(py4)s.VERDICT_PROVENANCE_ADOPTED
}recrP   r   r   r   )z[%(py2)s
{%(py2)s = %(py0)s.owner_key_class
} == %(py6)s
{%(py6)s = %(py4)s.OKC_PROVENANCE
}Fr   )z3%(py2)s
{%(py2)s = %(py0)s.quarantined
} is %(py5)sr   r   r      zK%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.calls
})
} == %(py8)slenwriterr   py1py3r   r   assert %(py10)spy10r   )z_%(py2)s
{%(py2)s = %(py0)s.adopted_via
} == %(py6)s
{%(py6)s = %(py4)s.ADOPTED_VIA_PROVENANCE
}r   crr   r   )z/%(py2)s
{%(py2)s = %(py0)s.task_id
} == %(py4)sr#   r   r   r   launchercallback_launchpickup)!r;   rS   rt   r   r   rK   r]   rP   process_onerY   	_NO_SLEEPr/   rg   VERDICT_PROVENANCE_ADOPTEDr   r   r   r   r   r   r   r   owner_key_classOKC_PROVENANCEquarantinedrq   r  adopted_viar  ADOPTED_VIA_PROVENANCEr   r   r#   )r:   r>   r  r  r  r  rJ   r  r   r   r   r   r   r   r   r   @py_assert2@py_assert7@py_assert6@py_format11r   _cr_pathr   r   s                           r'   #test_integration_provenance_adoptedr)    s%   hDtF!#H(*O&(FdAG
//ASY* $%-"	C ;;8#888;88888;888888838883888;888888#888#888888888884#"4"44"44444"444444434443444444444#444#444"44444444??#e#?e####?e######3###3###?###e####### ||!3|!!!!!!!!!!!!3!!!3!!!!!!v!!!v!!!|!!!!!!!!!!!!! ,,q/Ix  =B$=$== $===== $=======9===9=== ======B===B===$======== )))))))))9)))9))))))))))'''''''''''9'''9''''''''''''''''''' ~~#3~#!#!####!######3###3######x###x###~######!#######$$*3$%**%****%******3***3************$***%**********||!3|!!!!!!!!!!!!3!!!3!!!!!!v!!!v!!!|!!!!!!!!!!!!!r&   c                
   t        |       }t        |       t        d      }t        d      }t	        d      }t               }t        dd|d<   t        ||	      }t        |       t        j                  t        |      t        |      ||t        d|t               
      }|j                  }t        j                  }	||	k(  }
|
st!        j"                  d|
fd||	f      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*                  |	      dz  }dd|iz  }t-        t!        j.                  |            d x}x}
}	|j0                  }t        j2                  }	||	k(  }
|
st!        j"                  d|
fd||	f      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*                  |	      dz  }dd|iz  }t-        t!        j.                  |            d x}x}
}	|j4                  }t7        |      }d}||k(  }|s
t!        j"                  d|fd||f      dt%        j&                         v st!        j(                  t6              rt!        j*                  t6              nddt%        j&                         v st!        j(                  |      rt!        j*                  |      ndt!        j*                  |      t!        j*                  |      t!        j*                  |      dz  }dd|iz  }t-        t!        j.                  |            d x}x}x}}|j4                  }t7        |      }d}||k(  }|s
t!        j"                  d|fd||f      dt%        j&                         v st!        j(                  t6              rt!        j*                  t6              nddt%        j&                         v st!        j(                  |      rt!        j*                  |      ndt!        j*                  |      t!        j*                  |      t!        j*                  |      dz  }dd|iz  }t-        t!        j.                  |            d x}x}x}}y )Nre   )rg   rw   Tr   zsch-1)r   schedule_idcollector_enveloper   )r>   r  	verify_fnr
  r  provenance_fnr   r   )zW%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py6)s
{%(py6)s = %(py4)s.VERDICT_WAKE_BUILT
}r  rP   r   r   r   )zT%(py2)s
{%(py2)s = %(py0)s.owner_key_class
} == %(py6)s
{%(py6)s = %(py4)s.OKC_ANU
}r  r  r  verifyr  r  r  r   prov_spy)r;   rS   rt   r|   r   r(   r#   rK   r]   rP   r  rY   r  r/   rg   VERDICT_WAKE_BUILTr   r   r   r   r   r   r   r   r  OKC_ANUrq   r  )r:   r>   r  r0  r1  rI   rJ   r  r   r   r   r   r   r$  r   r%  r&  r'  s                     r'   )test_integration_envelope_path_regressionr4    s    hDtl3Fo6F"t4H oG07$PG !dG,AG
//ASYF $%-C ;;0#000;00000;000000030003000;000000#000#00000000000-#++-+----+------3---3---------#---#---+-------||!3|!!!!!!!!!!!!3!!!3!!!!!!v!!!v!!!|!!!!!!!!!!!!!~~#3~#!#!####!######3###3######x###x###~######!#######r&   c           	        t        |       }t        |       t               }t        d      }t	        |      }t        |       t        j                  t        |      t        |      |t        |t                     }|j                  }t        j                  }||k(  }|st        j                  d|fd||f      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$                  |      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}}|j,                  }t        j.                  }||k(  }|st        j                  d|fd||f      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$                  |      dz  }	d	d
|	iz  }
t'        t        j(                  |
            d x}x}}|j0                  }t3        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                          v st        j"                  t2              rt        j$                  t2              nddt        j                          v st        j"                  |      rt        j$                  |      ndt        j$                  |      t        j$                  |      t        j$                  |      dz  }
dd|
iz  }t'        t        j(                  |            d x}x}x}}|j0                  }t3        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                          v st        j"                  t2              rt        j$                  t2              nddt        j                          v st        j"                  |      rt        j$                  |      ndt        j$                  |      t        j$                  |      t        j$                  |      dz  }
dd|
iz  }t'        t        j(                  |            d x}x}x}}y )NTr+  )r>   r  r
  r/  r   r   )zW%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py6)s
{%(py6)s = %(py4)s.VERDICT_QUARANTINE
}r  rP   r   r   r   owner_unprovable)z9%(py2)s
{%(py2)s = %(py0)s.quarantine_reason
} == %(py5)sr   r   r   )zX%(py2)s
{%(py2)s = %(py0)s.owner_key_class
} == %(py6)s
{%(py6)s = %(py4)s.OKC_FOREIGN
}r   r  r  r1  r  r  r  r  )r;   rS   rt   r   rK   r]   rP   r  rY   r  r/   rg   VERDICT_QUARANTINEr   r   r   r   r   r   r   r   quarantine_reasonr  OKC_FOREIGNrq   r  )r:   r>   r  r1  rJ   r  r   r   r   r   r   r   r   r   r$  r%  r&  r'  s                     r'   5test_integration_flag_off_owner_unprovable_regressionr:    sL   hDtF"t4HdAG //ASY%-C ;;0#000;00000;000000030003000;000000#000#00000000000  6$66 $66666 $666666636663666 666$666666661#//1/1111/11111131113111111111#111#111/1111111~~#3~#!#!####!######3###3######x###x###~######!#######||!3|!!!!!!!!!!!!3!!!3!!!!!!v!!!v!!!|!!!!!!!!!!!!!r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)uE   task_id='../evil' → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL.../evilr   any.jsonr   Fr   r   r   r   r   r   Nr   za%(py2)s
{%(py2)s = %(py0)s.reason
} == %(py6)s
{%(py6)s = %(py4)s.REASON_TASK_ID_PATH_TRAVERSAL
}r   r   r   r   r;   r(   r   r   rY   r/   rh   r   r   r   r   r   r   r   r   r   REASON_TASK_ID_PATH_TRAVERSALr:   r>   rI   r   r   r   r   r   r   r   r   r   s               r'   (test_unit_task_id_traversal_dotdot_slashrB    sJ   hDoG"GI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)uG   task_id='/tmp/evil' → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL.z	/tmp/evilr   r=  r   Fr   r   r   r   r   r   Nr   r>  r   r   r   r   r?  rA  s               r'   $test_unit_task_id_traversal_absoluterD  "  sJ   hDoG$GI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)uP   task_id='a\b' (백슬래시) → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL.a\br   r=  r   Fr   r   r   r   r   r   Nr   r>  r   r   r   r   r?  rA  s               r'   %test_unit_task_id_traversal_backslashrG  /  sJ   hDoGGI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)uA   task_id='a/b' → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL.a/br   r=  r   Fr   r   r   r   r   r   Nr   r>  r   r   r   r   r?  rA  s               r'   )test_unit_task_id_traversal_forward_slashrJ  <  sJ   hDoGGI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)u   task_id='..%2fevil' → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL.
    '%' 가 whitelist([A-Za-z0-9._+-]) 밖이므로 거부됨.z	..%2fevilr   r=  r   Fr   r   r   r   r   r   Nr   r>  r   r   r   r   r?  rA  s               r'   'test_unit_task_id_traversal_url_encodedrL  I  sL    hDoG$GI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                p   t        |       }t               }d|d<   t        j                  |t	        | dz        t	        |      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                  }t        j                   }	||	k(  }|st        j                  d|fd||	f      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                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)u@   task_id='..' → ok=False, reason=REASON_TASK_ID_PATH_TRAVERSAL...r   r=  r   Fr   r   r   r   r   r   Nr   r>  r   r   r   r   r?  rA  s               r'   'test_unit_task_id_traversal_dotdot_barerO  W  sJ   hDoGGI		*	*X
*+#d)%-
B 55E5E>5E225E99::::9:::::9:::::::2:::2:::9::::::::::::::::::::r&   c                   t        |       }t        j                  }d}t        |      } |||      }d}||u }|s{t	        j
                  d|fd||f      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      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                  |      t	        j                  |      dz  }d	d
|iz  }	t        t	        j                  |	            dx}x}x}x}x}}y)uW  caps_root 밖으로 escape 하는 task_id 는 None 반환.

    _safe_capability_path 의 책임은 realpath+commonpath 에 의한 caps_root 밖 escape 방어.
    separator 포함('a/b') 은 caps_root 내부 경로로 resolve 되므로 None 이 아니며,
    separator 거부는 _validate_task_id_safe(whitelist 계층)가 담당한다.
    z../../etc/passwdNr   )z%(py10)s
{%(py10)s = %(py2)s
{%(py2)s = %(py0)s._safe_capability_path
}(%(py4)s, %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
})
} is %(py13)sr   rY   r>   )r   r   r   r   r   r   r  py13zassert %(py15)spy15)r;   r   _safe_capability_pathrY   r   r   r   r   r   r   r   r   )
r:   r>   r   r   r%  @py_assert9@py_assert12@py_assert11@py_format14@py_format16s
             r'   2test_unit_safe_capability_path_escape_returns_nonerY  f  s    hD%%L&8L#d)L%&8)DLLDLLLLDLLLLLL4LLL4LLL%LLL&8LLLLLL#LLL#LLLLLLdLLLdLLL)LLLDLLLLLLLLLLLr&   c           	        t        |       }t        j                  dt        |            }d}||u}|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}}t        j                  j                  t        j                  j                  t        |      d	d
            }t        j                  }|j                   }||g}	 ||	      }
|
|k(  }|st	        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                  |	      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}x}x}	x}
}y)u1   safe task_id 는 caps_root 안으로 resolve 됨.r   Nr
   )z%(py0)s is not %(py3)srJ   )r   r  zassert %(py5)sr   r1   r8   r   )zk%(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.commonpath
}(%(py6)s)
} == %(py10)srW   	caps_root)r   r   r   r   r   r  zassert %(py12)spy12)r;   r   rS  rY   r   r   r   r   r   r   r   r   rW   rZ   realpathjoin
commonpath)r:   r>   rJ   r$  r   @py_format4r   r[  r   r   r%  rT  r'  @py_format13s                 r'   3test_unit_safe_capability_path_safe_resolves_insiderb  r  sf   hD"";D	:A1D=1D11D  c$i>!RSI77:7:y!n:n-:-::::-::::::2:::2:::7::::::n:::-:::::::::::::::::r&   c                   t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d
} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}t         j                  }d} ||      }d}||u }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}x}}y	)u9   _validate_task_id_safe whitelist/거부 패턴 총망라.r   Tr   )z\%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s._validate_task_id_safe
}(%(py4)s)
} is %(py9)sr   )r   r   r   r   r   zassert %(py11)sr   Nztask-2753+1r<  FrI  rF  r   rN  )
r   _validate_task_id_safer   r   r   r   r   r   r   r   )r:   r   r   r   @py_assert8r%  @py_format10@py_format12s           r'   )test_unit_validate_task_id_safe_whitelistrh  {  s4   &&;{;&{3;t;3t;;;;3t;;;;;;4;;;4;;;&;;;{;;;3;;;t;;;;;;;&&=}=&}5==5====5======4===4===&===}===5==========&&:y:&y1:U:1U::::1U::::::4:::4:::&:::y:::1:::U:::::::&&6u6&u-66-6666-66666646664666&666u666-6666666666&&7v7&v.7%7.%7777.%77777747774777&777v777.777%7777777&&3r3&r*3e3*e3333*e33333343334333&333r333*333e3333333&&5t5&t,55,5555,55555545554555&555t555,55555555555r&   c                   t        |       }|dz  dz  t         dz  }|j                  t        j                  t        t
        d      d       t        |      }t        j                  t               t        |      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)u[   safe task_id + capability JSON 실재 → capability_reader 미주입(default) → ok=True.r1   r8   z.jsonr)   rB   rC   r=   Tr   r   r   r   r   r   N)r;   r#   rE   rF   rG   r$   rK   r   r   r(   rY   rh   r   r   r   r   r   r   r   r   )
r:   r>   cap_jsonrJ   r   r   r   r   r   r   s
             r'   .test_unit_safe_task_id_default_reader_resolvesrk    s    hDh/WIU2CCH

wEF   	dA		*	*=?CFT	SB55D5D=5D225Dr&   c                   ddl }t        |       }|dz  }|j                  d       t        j                  }t        |      } ||      }|j                  }|j                  } |       }	 ||	      }
|
j                  } |       }||k(  }|sMt        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      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
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |	      t        j                  |
      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            dx}x}x}x}x}x}x}	x}
x}}|dz  }ddz  }|j                  |       t        j                  }t        |      } ||      }|j                  } ||      }|j                  }	 |	       }
||
k(  }|s%t        j                  d|fd||
f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      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
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      t        j                  |
      dz  }dd|iz  }t        t        j                   |            dx}x}x}x}x}x}x}	}
y)uW   _default_hash_fn 이 작은 파일과 >1 MiB 파일 모두 full-read sha256 과 일치.r   Nz	small.bins   hello-provenance-2753r   )a)  %(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s._default_hash_fn
}(%(py6)s
{%(py6)s = %(py3)s(%(py4)s)
})
} == %(py23)s
{%(py23)s = %(py21)s
{%(py21)s = %(py19)s
{%(py19)s = %(py12)s
{%(py12)s = %(py10)s.sha256
}(%(py17)s
{%(py17)s = %(py15)s
{%(py15)s = %(py13)s.read_bytes
}()
})
}.hexdigest
}()
}r   rY   smallr   )r   r   r  r   r   r   r  r\  rQ  rR  py17r   py21py23zassert %(py25)spy25zbig.bin   Ai{   z%(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s._default_hash_fn
}(%(py6)s
{%(py6)s = %(py3)s(%(py4)s)
})
} == %(py19)s
{%(py19)s = %(py17)s
{%(py17)s = %(py15)s
{%(py15)s = %(py12)s
{%(py12)s = %(py10)s.sha256
}(%(py13)s)
}.hexdigest
}()
}bigdatar   r   r  r   r   r   r  r\  rQ  rR  rn  r   assert %(py21)sro  )r   r;   write_bytesr   _default_hash_fnrY   r   r   r   r   r   r   r   r   r   r   r   )r:   r   r>   rm  r   r   r%  rV  @py_assert14@py_assert16@py_assert18@py_assert20@py_assert22rT  @py_format24@py_format26rt  ru  @py_format20@py_format22s                       r'   (test_unit_chunked_hash_matches_full_readr    sG   hD ;E	./  ^U^ ,^^u?O?O^?O?Q^?Q0R^0R0\0\^0\0^^,0^^^^^,0^^^^^^^4^^^4^^^ ^^^^^^^^^^^^^^^U^^^U^^^^^^,^^^^^^^^^^^^^^^^^^u^^^u^^^?O^^^?Q^^^0R^^^0\^^^0^^^^^^^^^^ 
C()DOOD  NSN *NgnnNnT.BN.B.L.LN.L.NN*.NNNNN*.NNNNNNN4NNN4NNN NNNNNNNNNNNNNNNSNNNSNNNNNN*NNNNNNgNNNgNNNnNNNNNNTNNNTNNN.BNNN.LNNN.NNNNNNNNNr&   c                   ddl }t        |       }|j                  t        dd       |dz  }d}|j	                  |       t        j
                  }t        |      } ||      }|j                  }	 |	|      }
|
j                  } |       }||k(  }|s%t        j                  d|fd||f      d	t        j                         v st        j                  t              rt        j                  t              nd	t        j                  |      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t        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |
      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            dx}x}x}x}x}	x}
x}}y)ud   chunk 크기를 7 byte 로 monkeypatch 하여도 hash 결과가 동일 = streaming 정확성 증명.r   N_HASH_CHUNK_SIZE   z
stream.binsd   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXr   rs  r   rY   fr   ru  rv  rw  ro  )r   r;   setattrr   rx  ry  rY   r   r   r   r   r   r   r   r   r   r   )r:   monkeypatchr   r>   r  ru  r   r   r%  rV  rz  r{  r|  rT  r  r  s                   r'   2test_unit_chunked_hash_large_stream_no_full_bufferr    s   hD0!4|ADMM$  LQL (LGNNLN4,@L,@,J,JL,J,LL(,LLLLL(,LLLLLLL4LLL4LLL LLLLLLLLLLLLLLLQLLLQLLLLLL(LLLLLLGLLLGLLLNLLLLLL4LLL4LLL,@LLL,JLLL,LLLLLLLLLr&   c                X   t        |       }t        |       t        |      }t        |       d }t	        j
                  t        |      t        |      t               t               t               t        dt               |	      }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |      dz  }t#        t        j$                  |            dx}}g }|j&                  }|}|rd}	|j&                  }
|	|
v }|}|sLd	d
t        j                         v st        j                  |      rt        j                   |      nd
t        j                   |      dz  }|j)                  |       |rt        j*                  dfd	
f      t        j                   |	      d
t        j                         v st        j                  |      rt        j                   |      nd
t        j                   |
      dz  }dd|iz  }|j)                  |       t        j,                  |d      i z  }dd|iz  }t#        t        j$                  |            dx}x}x}x}	x}}
y)ub   collector_writer_fn 이 OSError 를 raise 하면 source 파일은 inbox 원위치에 보존된다.c                    t        d      )Nzdisk full simulated)OSError)r   rZ   s     r'   _failing_writerzQtest_integration_move_blocked_when_collector_write_fails.<locals>._failing_writer  s    +,,r&   Tr  zAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}rJ   r   Nu   collector_result write 실패z"%(py4)s
{%(py4)s = %(py2)s.error
}r  )r   r   )in)z/%(py7)s in %(py11)s
{%(py11)s = %(py9)s.error
})r   r   r   z%(py13)srQ  r   zassert %(py16)sr   )r;   rS   rK   r]   rP   r  rY   rt   r   r  r/   existsr   r   r   r   r   r   r   errorrk   r   _format_boolop)r:   r>   rJ   r  r  r   r   r   @py_assert0r&  @py_assert10re  rg  rW  @py_format15@py_format17s                   r'   8test_integration_move_blocked_when_collector_write_failsr    s   hDtdAG- //ASY"$&(-/ $%-+	C 888::118:E399E9E98ECIIE8IEEEEEEE3EEE3EEE9EEEE9EEE8IEEE8EEEEEECEEECEEEIEEEEEEEEEEEEEEr&   c                   t        |       }t        |       t        |      }t        |       t	               }t        j                  t        |      t        |      t               t               t               t        dt               |	      }|j                  }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&                  |      t        j&                  |      dz  }	d	d
|	iz  }
t)        t        j*                  |
            dx}x}x}}|j,                  } |       }| }|sddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      t        j&                  |      dz  }t)        t        j*                  |            dx}x}}|j.                  }t
        j0                  }||k(  }|st        j                  d|fd||f      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&                  |      dz  }dd|iz  }	t)        t        j*                  |	            dx}x}}y)u_   collector_writer_fn 성공 시 source 가 inbox 에서 이동되고 verdict=PROVENANCE_ADOPTED.Tr  r  r   r  r  r  r  r  r  NzEassert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}rJ   r   r  r  rP   r   r   r   )r;   rS   rK   r]   r   rP   r  rY   rt   r   r  r/   rq   r  r   r   r   r   r   r   r   r   r  rg   r  )r:   r>   rJ   r  r  r$  r   r%  r&  r   r'  r   r   r   r   r   s                   r'   3test_integration_move_after_collector_write_successr    s   hDtdAG&(F
//ASY"$&(-/ $%-"	C ||!3|!!!!!!!!!!!!3!!!3!!!!!!v!!!v!!!|!!!!!!!!!!!!!xxxzz>>qqxz;;8#888;88888;888888838883888;888888#888#88888888888r&   )returndict)r:   r   r  r   )r>   r   r  r   )NN)r>   r   r  None)g      $@)r[   floatr  r  )re   )rg   rY   )rw   )T)s__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   rF   rW   sysrV   rU   rl   pathlibr   r   resolver5   _ROOTrY   rZ   insertimportlib.utilutil_ilu
_real_initmodulesget_cachedgetattrlist
startswith_kspec_from_file_locationr   r   r   r   r  loaderr  @py_assert13rU  r   r   r   r   r   r   rk   r  r  r  @py_format18r  r   r   module_from_spec_pkgexec_moduler   r   rP   r   r   r   r  r#   r$   r   r(   r/   r;   r?   rK   rS   r]   r  rt   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r)  r4  r:  rB  rD  rG  rJ  rL  rO  rY  rb  rh  rk  r  r  r  r  )ra   s   0r'   <module>r     s  * #    	 
    	X ((+u:SXXHHOOAs5z" Z-/

++//*
%
?ww
B7=2#j/Qs{{+\QqJ!,,{B[q\ KKO(D((JC
@R<S;TE :9599T9T!9999599999599959999999999T9999999999999T9999999999999 4  'D"CKK
	LLT" - 4 / 1
 #+ L4	E& !	 		"/&759
8
0
59 
3
9
3
.(V("Z$B"@
;
;
;
;;
;	M;6 O"MF:9E ]s    N<N