
    Jje?                       S r SSKJr  SSKrSSKJs  Jr  SSK	r	SSK
r
SSKrSSKJr  \
R                  R                  S\" \" \5      R%                  5       R&                  S   S-  5      5        SS jrS rS	 rS
 rS rS rS rS rS rS rS rS rS r S r!S r"S r#S r$\%S:X  a  SSK&r&\'" \(" 5       RS                  5       5       V Vs/ sH  u  pU RU                  S5      (       d  M  UPM!     snn r+Sr,\+ Hc  r- S\-R\                  R^                  ;   a)  \R`                  " 5        r1\-" \" \15      5        SSS5        O\-" 5         \2" S\-RJ                   35        Me     \
Rj                  " \,(       a  SOS5        ggs  snn f ! , (       d  f       NJ= f! \3 a/    \,S-  r,\2" S\-RJ                   35        \&Rh                  " 5          M  f = f)a  Basic smoke tests for the WolfPanel Agent v1 foundation.

Run with:  python -m pytest tests/   (or: python tests/test_basic.py)

These tests use a temporary WOLFPANEL_DEV_HOME so nothing touches real system
paths, and the mock API so no network is required.
    )annotationsN)Path   srcc                    U [         R                  S'   S[         R                  S'   SS KnSS KnUR	                  U5        UR                  5       $ )NWOLFPANEL_DEV_HOME1WOLFPANEL_API_MOCKr   )osenviron	importlibconfigreloadload_config)tmpr   config_modules      6D:\Programs\laragon\www\wolf\agent\tests\test_basic.py_fresh_configr      sC    '*BJJ#$'*BJJ#$"]#$$&&    c                 J   [         R                  " 5        n [        U 5      nUR                  n[	        U5      o3R
                  oD" U 5      oU(       Gdb  SS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      S.-  n[        [        R                  " U5      5      eS =n=n=pEUR                  owR                  nSoHU:H  o(       d  [        R                  " SU	4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S	.-  n
S
SU
0-  n[        [        R                  " U5      5      eS =n=n=pUR                   nSo7U:H  o(       d  [        R                  " SU4SXs45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n
[        [        R                  " U
5      5      eS =n=pS S S 5        g ! , (       d  f       g = f)Nzassert %(py10)s
{%(py10)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.conf_file
})
}.startswith
}(%(py8)s)
}strcfgr   )py0py1py3py5py7py8py10secrets==)zM%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.secrets_dir
}.name
} == %(py7)sr   py2py4r   assert %(py9)spy9<   )z:%(py2)s
{%(py2)s = %(py0)s.heartbeat_interval
} == %(py5)sr   r$   r   assert %(py7)sr   )tempfileTemporaryDirectoryr   	conf_filer   
startswith@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationsecrets_dirname_call_reprcompareheartbeat_interval)r   r   @py_assert2@py_assert4@py_assert6@py_assert9@py_format11@py_assert1@py_assert3@py_assert5@py_format8@py_format10@py_format6s                r    test_config_paths_under_dev_homerE      s   		$	$	&#C ==1s=!1,,1,S111111111s1111s111111311113111=111!111,111111S1111S11111111110##0y0y00000#000000s0000s000000#000y0000000%%+++++++%++++++s++++s+++%++++++++++	 
'	&	&s   M5N
N"c                    SSK Jn   U " 5       nU " 5       nX:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSS	U0-  n[        [        R                  " U5      5      eS nUR                  nS
oc" U5      ow(       d  SS[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS =n=pgg )Nr   )generate_fingerprintr!   )z%(py0)s == %(py2)sfp1fp2r   r$   assert %(py4)sr%   fp_zLassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}r   r$   r%   py6)identityrG   r1   r8   r/   r0   r2   r3   r4   r5   r.   )	rG   rH   rI   r?   @py_format3@py_format5r@   rA   @py_format7s	            r   %test_fingerprint_is_stable_and_opaquerS   &   s    -

 C

 C:333##>> % >%         3    3   >   %          r   c                    [         R                  " 5        n [        U 5      nSSKJn  SSKJnJnJn  U" U5        U" U5      R                  SSS.5      nU" U[        US   5      US   5        UR                  owR                  o" 5       oR                  o" 5       oR                  nS	o" U5      o(       Gd  S
S[        R                   " 5       ;   d  ["        R$                  " U5      (       a  ["        R&                  " U5      OS["        R&                  " U5      ["        R&                  " U5      ["        R&                  " U	5      ["        R&                  " U
5      ["        R&                  " U5      ["        R&                  " U5      ["        R&                  " U5      ["        R&                  " U5      S.	-  n[)        ["        R*                  " U5      5      eS =n=n=n	=n
=n=n=pU" U5      nSn	UU	:H  nU(       Gd  ["        R,                  " SU4SUU	45      S[        R                   " 5       ;   d  ["        R$                  " U5      (       a  ["        R&                  " U5      OSS[        R                   " 5       ;   d  ["        R$                  " U5      (       a  ["        R&                  " U5      OS["        R&                  " U5      ["        R&                  " U	5      S.-  nSSU0-  n[)        ["        R*                  " U5      5      eS =n=nn	[/        U 5      R1                  S5       GH>  nUR3                  5       (       d  M  UUR                  :X  a  M-  SnUR                  nSnU" US9nUU;  nU(       d  ["        R,                  " SU4SUU45      ["        R&                  " U5      S[        R                   " 5       ;   d  ["        R$                  " U5      (       a  ["        R&                  " U5      OS["        R&                  " U5      ["        R&                  " U5      ["        R&                  " U5      S.-  nSSU0-  n[)        ["        R*                  " U5      5      eS =n=n=n=nnGMA     S S S 5        g ! , (       d  f       g = f)Nr   get_api_client)ensure_dirsload_agent_tokenstore_credentialstfp_x)hostnamefingerprint	server_idagent_tokenzwp_enc:zassert %(py16)s
{%(py16)s = %(py12)s
{%(py12)s = %(py10)s
{%(py10)s = %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.agent_token_file
}.read_text
}()
}.strip
}()
}.startswith
}(%(py14)s)
}r   )	r   r$   r%   rN   r   r   py12py14py16wp_agent_dev_tokenr!   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)srX   r   r   r   rN   assert %(py8)sr   *install_tokenignore)errorsnot in)zZ%(py1)s not in %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s.read_text
}(errors=%(py7)s)
}path)r   r   r   r   r'   assert %(py11)spy11)r+   r,   r   
api_clientrV   rO   rW   rX   rY   registerr   agent_token_file	read_textstripr.   r/   r0   r1   r2   r3   r4   r5   r8   r   rglobis_file)r   r   rV   rW   rX   rY   respr?   r@   rA   @py_assert7r=   @py_assert11@py_assert13@py_assert15@py_format17r:   r;   rR   @py_format9rm   @py_assert0r<   @py_assert8rC   @py_format12s                             r   6test_register_stores_credentials_and_not_install_tokenr   /   s   		$	$	&#C -MMCc"++V,TU#s4#45tM7JK ##M--M-/M55M57MBBM9MB9MMMMMMMMMsMMMMsMMM#MMM-MMM/MMM5MMM7MMMBMMM9MMMMMMMMMMM$<(<<$(<<<<<<$(<<<<<<<<<<<<<<<<<<<<<<<<$<<<(<<<<<<<<IOOC(D||~~3///&MdnnMHMnH.MM.MMMMMM.MMMMMMMMMMdMMMMdMMMnMMMHMMM.MMMMMMMMM	 ) 
'	&	&s   LQ&5D(Q&&
Q4c                    SSK Jn   U R                  5       nS H  nX!;   o3(       d  [        R                  " SU4SX!45      S[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nS	S
U0-  n[        [        R                  " U5      5      eS nM     g )Nr   )quick)r\   r   architecture	cpu_countprivate_ipsin)z%(py0)s in %(py2)skeysnapshotrJ   rK   r%   )	discoveryr   collectr1   r8   r/   r0   r2   r3   r4   r5   )r   r   r   r?   rP   rQ   s         r   *test_quick_discovery_returns_expected_keysr   E   s    }}HMssshh Nr   c                    SSK Jn   SnU " U5      nSnUU:H  oD(       d  [        R                  " SU4SUU45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=pCSo" U5      nSo2U:H  oD(       d  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=pCg )Nr   )sanitize_remotez*https://user:ghp_secret@github.com/a/b.gitzhttps://github.com/a/b.gitr!   z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   r#   r&   r'   zgit@github.com:a/b.git)
discovery.gitr   r1   r8   r/   r0   r2   r3   r4   r5   )r   r?   r@   r<   rA   rB   rC   s          r   test_git_remote_sanitizationr   M   sv   - EDE'E'	(  E'        D  E  '       4P?34P8PP8PPPPPP4PPPPPP?PPPP?PPP3PPP4PPP8PPPPPPPPr   c                v   SSK Jn  U S-  R                  S5        U S-  R                  S5        U" U 5      S   nSo2U:H  oD(       do  [        R                  " S	U4S
X#45      [        R
                  " U5      [        R
                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pCg )Nr   )classifyartisan zcomposer.jsonz{}typelaravelr!   z%(py1)s == %(py4)sr   r%   assert %(py6)srN   )discovery.projectsr   
write_textr1   r8   r3   r4   r5   )tmp_pathr   r~   r@   r:   rQ   rR   s          r   test_project_classificationr   W   s    +	%%b)++D1Hf%2222222%222%2222222222r   c                 (   [         R                  " 5        n [        U 5      nSSKJn  SSKJn  U" X" U5      5      n/ nS odULowo(       a  UR                  n	SoU
L onU(       Gd  [        R                  " SU4SXF45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  nS	S
U0-  oR                  U5        U(       a  [        R                  " SW4SW	W
45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      [        R                  " U
5      S.-  nSSU0-  oR                  U5        [        R                  " US5      0 -  nSSU0-  n[!        [        R"                  " U5      5      eS =n=n=n=n=n	=pS S S 5        g ! , (       d  f       g = f)Nr   rU   )checkT)is not)z%(py2)s is not %(py5)sinfo)r$   r   z%(py7)sr   is)z;%(py11)s
{%(py11)s = %(py9)s.update_available
} is %(py14)s)r'   ro   ra   z%(py16)srb   zassert %(py19)spy19)r+   r,   r   rp   rV   updater   update_availabler1   r8   r/   r0   r2   r3   append_format_boolopr4   r5   )r   r   rV   r   r   r?   r;   r@   r~   @py_assert10rz   @py_assert12rD   rB   @py_format15r|   @py_format18@py_format20s                     r   test_update_version_comparisonr   _   s   		$	$	&#C - S.-.A4A4AD$9$9ATAT$AAAAAtAAAAAAtAAAAtAAA4AAAAAAAA$9TAAAAAADAAAADAAA$9AAATAAAAAAAAAAAAAA 
'	&	&s   G$H
Hc                    SSK Jn   U R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  nSo!" U5      nSoCUL oU(       d  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=pTU R                  5        GH  nU R                  o" U5      o(       d  SS[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      S[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      S.-  n
[        [        R                  " U
5      5      eS =pGM     g )Nr   )systemz10.0.0.5Tr   )zV%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s._is_private_ipv4
}(%(py4)s)
} is %(py9)sr   )r   r$   r%   rN   r'   rn   ro   z192.168.1.10z
172.16.4.4z	127.0.0.1z169.254.1.1z8.8.8.8Fz
172.32.0.1z	not-an-ipzRassert %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s._is_private_ipv4
}(%(py3)s)
}ip)r   r$   r   r   )r   r   _is_private_ipv4r1   r8   r/   r0   r2   r3   r4   r5   r   )r   r?   r@   rA   r   rx   rC   r   r   r;   rD   s              r   *test_private_ips_excludes_public_addressesr   j   sp    ""6:6":.6$6$66666.666666666666666"666:666.666$6666666"":>:">2:d:d:::::2::::::6::::6:::":::>:::2:::d:::::::""8<8"<08D8D888880888888688886888"888<8880888D8888888""7;7";/747477777/777777677776777"777;777/77747777777""9=9"=19T9T999991999999699996999"999=9991999T9999999""696"9-6666666-666666666666666"6669666-6666666666""9<9"<09E9E999990999999699996999"999<9990999E9999999""8;8";/858588888/888888688886888"888;888/88858888888  "&&*&r*********v****v***&******r****r********** #r   c                    [         R                  " 5        n [        U 5      nSSKJnJnJn  U" U5        U" US5        U" US5        UR                  oUR                  of" 5       ow(       d  SS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS =n=pgUR                  R!                  5       n	SoU	;   o(       d  [        R"                  " SU4S	X45      [        R                  " U
5      S
[        R                  " 5       ;   d  [        R                  " U	5      (       a  [        R                  " U	5      OS
S.-  nSSU0-  n[        [        R                  " U5      5      eS =pSoU	;   o(       d  [        R"                  " SU4S	X45      [        R                  " U
5      S
[        R                  " 5       ;   d  [        R                  " U	5      (       a  [        R                  " U	5      OS
S.-  nSSU0-  n[        [        R                  " U5      5      eS =pUR$                  R                  5       (       Ga  UR$                  R!                  5       nSoU;  o(       d  [        R"                  " SU4SX45      [        R                  " U
5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS =pSoU;  o(       d  [        R"                  " SU4SX45      [        R                  " U
5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS =pS S S 5        g ! , (       d  f       g = f)Nr   )rW   save_last_errorsave_statusrevokedzline1
line2zbassert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.state_file
}.is_file
}()
}r   rM   r   )z%(py1)s in %(py3)s
state_text)r   r   assert %(py5)sr   zline1 line2WOLFPANEL_STATUSrk   )z%(py1)s not in %(py3)s	conf_textWOLFPANEL_LAST_ERROR)r+   r,   r   rO   rW   r   r   
state_filerv   r/   r0   r1   r2   r3   r4   r5   rs   r8   r-   )r   r   rW   r   r   r?   r@   rA   rR   r   r~   r:   @py_format4rD   r   s                  r   ,test_runtime_state_not_written_to_agent_confr   {   sg   		$	$	&#C FFCC#^, ~~'%%'%'''''''''s''''s'''~'''%''''''''''^^--/
&J&&&&&y&&&y&&&&&&J&&&&J&&&&&&&*
*****}***}******
****
*******==  ""//1I%6Y66666%666%666666Y6666Y6666666)::::::):::):::::::::::::::::# 
'	&	&s   P+Q


Qc                 $  ^ [         R                  " 5        n [        U 5      nSSKJnJm  SSKJn  SSKJ	n  U" U5         " U4S jSU5      nU" 5       nU" X5      nSoUL o(       d  [        R                  " SU	4S	Xx45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
[        R                  " U5      S.-  n
SSU
0-  n[!        [        R"                  " U5      5      eS =pUR$                  n	SoU:H  o(       d  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      [        R                  " U5      S.-  nSSU0-  n[!        [        R"                  " U5      5      eS =n	=pUR&                  n	SoU:H  o(       d  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      [        R                  " U5      S.-  nSSU0-  n[!        [        R"                  " U5      5      eS =n	=pU" X5      nSoUL o(       d  [        R                  " SU	4S	X45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  n
SSU
0-  n[!        [        R"                  " U5      5      eS =pS S S 5        g ! , (       d  f       g = f)Nr   )	ApiClientApiError	send_oncerW   c                  "   > \ rS rSrU 4S jrSrg)4test_heartbeat_revoked_on_401.<locals>.Mock401Client   c                   > T" SSS9e)NUnauthorizedi  )status_code )selfpayloadtokenr   s      r   	heartbeat>test_heartbeat_revoked_on_401.<locals>.Mock401Client.heartbeat   s    ~3??r   r   N)__name__
__module____qualname____firstlineno__r   __static_attributes__)r   s   r   Mock401Clientr      s    @ @r   r   Fr   z%(py0)s is %(py3)ssuccessr   r   r   r   r   r!   )z.%(py2)s
{%(py2)s = %(py0)s.status
} == %(py5)sr   r)   r*   r   r   )z2%(py2)s
{%(py2)s = %(py0)s.last_error
} == %(py5)ssuccess2)r+   r,   r   rp   r   r   r   r   rO   rW   r1   r8   r/   r0   r2   r3   r4   r5   status
last_error)r   r   r   r   rW   r   clientr   r:   r?   r   rD   r;   r@   rB   r   r   s                   @r   test_heartbeat_revoked_on_401r      s   		$	$	&#C 2'(C	@I 	@ C(%www%zz&Y&Y&&&&&z&&&&&&s&&&&s&&&z&&&Y&&&&&&&~~///////~//////s////s///~////////// S)  5     x      x    x   5       ) 
'	&	&s   M!N
Nc                 4  ^^ [         R                  " 5        n [        U 5      nSSKJn  SSKJn  SSKJn  U" U5        / m/ m " UU4S jSU5      nU" 5       nSUl	        SS KnSUl
        S Ul        S	Ul        U" X5      nS
oU	L o(       d  [        R                  " SU
4SX45      S[        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS[        R$                  " U	5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =p[+        T5      n	SoU:H  o(       Gd  [        R                  " SU4SX45      S[        R                   " 5       ;   d  [        R"                  " [*        5      (       a  [        R$                  " [*        5      OSS[        R                   " 5       ;   d  [        R"                  " T5      (       a  [        R$                  " T5      OS[        R$                  " U	5      [        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n	=pTS   S   nUR,                  nUU:H  o(       d  [        R                  " SU	4SUU45      [        R$                  " U5      S[        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS[        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n=pTS   S   nS nUU:H  o(       dp  [        R                  " SU	4S!UU45      [        R$                  " U5      [        R$                  " U5      S".-  nS#S$U0-  n['        [        R(                  " U5      5      eS =n=n	nTS   S%   nS
nUUL o(       dp  [        R                  " SU	4S&UU45      [        R$                  " U5      [        R$                  " U5      S".-  nS#S$U0-  n['        [        R(                  " U5      5      eS =n=n	n[+        T5      n	SoU:H  o(       Gd  [        R                  " SU4SX45      S[        R                   " 5       ;   d  [        R"                  " [*        5      (       a  [        R$                  " [*        5      OSS'[        R                   " 5       ;   d  [        R"                  " T5      (       a  [        R$                  " T5      OS'[        R$                  " U	5      [        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n	=pU" X5      nS
n	UU	L o(       d  [        R                  " SU
4SUU	45      S([        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS([        R$                  " U	5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =p[+        T5      n	S)oU:H  o(       Gd  [        R                  " SU4SX45      S[        R                   " 5       ;   d  [        R"                  " [*        5      (       a  [        R$                  " [*        5      OSS[        R                   " 5       ;   d  [        R"                  " T5      (       a  [        R$                  " T5      OS[        R$                  " U	5      [        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n	=pTS   S   nUR,                  nUU:H  o(       d  [        R                  " SU	4SUU45      [        R$                  " U5      S[        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS[        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n=pTS   S   nS nUU:H  o(       dp  [        R                  " SU	4S!UU45      [        R$                  " U5      [        R$                  " U5      S".-  nS#S$U0-  n['        [        R(                  " U5      5      eS =n=n	nTS   S%   nS
nUUL o(       dp  [        R                  " SU	4S&UU45      [        R$                  " U5      [        R$                  " U5      S".-  nS#S$U0-  n['        [        R(                  " U5      5      eS =n=n	n[+        T5      n	SoU:H  o(       Gd  [        R                  " SU4SX45      S[        R                   " 5       ;   d  [        R"                  " [*        5      (       a  [        R$                  " [*        5      OSS'[        R                   " 5       ;   d  [        R"                  " T5      (       a  [        R$                  " T5      OS'[        R$                  " U	5      [        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS =n	=pS S S 5        g ! , (       d  f       g = f)*Nr   r   r   r   c                  .   > \ rS rSrU4S jrU 4S jrSrg);test_heartbeat_payload_has_version_info.<locals>.MockClient   c                (   > TR                  U5        g )Nr   )r   r   r   payloadss      r   r   Etest_heartbeat_payload_has_version_info.<locals>.MockClient.heartbeat   s    (r   c           	     <   > TR                  U5        SSSSSSSSS	.$ 
Nr   stable0.1.2zwolfpanel-agent-0.1.2.tar.gz@0000000000000000000000000000000000000000000000000000000000000000r   r   z2026-07-04T00:00:00Z)manifest_versionchannelversionfilesha256	signature
size_bytespublished_atr   )r   urlfetch_manifest_callss     r   fetch_manifestJtest_heartbeat_payload_has_version_info.<locals>.MockClient.fetch_manifest   s3    $++C0()'&:&!#"#$:	 	r   r   N)r   r   r   r   r   r   r   )r   r   s   r   
MockClientr      s    ) r   r   
   g        FTr   r   r   r   r   r   r   r!   rd   lenr   re   rf   r   agent_version)z5%(py1)s == %(py5)s
{%(py5)s = %(py3)s.agent_version
}r   )r   r   r   r*   r   latest_versionr   r   r   r   rN   r   z%(py1)s is %(py4)sr   r      )r+   r,   r   rp   r   r   r   rO   rW   r9   _last_fetch_time_cached_latest_version_cached_update_availabler1   r8   r/   r0   r2   r3   r4   r5   r   r   )r   r   r   r   rW   r   r   r   r   r:   r?   r   rD   rA   r;   rR   r}   r~   rB   r@   rQ   r   r   r   s                         @@r   'test_heartbeat_payload_has_version_infor     s   		$	$	&#C ('(C!	 	 	" !# 	%(	"+/	(-2	* C($www$8}!!!!!!!}!!!!!!s!!!!s!!!!!!8!!!!8!!!}!!!!!!!!!!{?+@s/@/@@+/@@@@@@+/@@@@+@@@@@@s@@@@s@@@/@@@@@@@@{+,77,77777,777,7777777777{-.6$6.$66666.$666.666$6666666'(-A-A-----(------s----s------'----'---(---A------- S)x4x4xx48}!!!!!!!}!!!!!!s!!!!s!!!!!!8!!!!8!!!}!!!!!!!!!!{?+@s/@/@@+/@@@@@@+/@@@@+@@@@@@s@@@@s@@@/@@@@@@@@{+,77,77777,777,7777777777{-.6$6.$66666.$666.666$6666666'(-A-A-----(------s----s------'----'---(---A-------m 
'	&	&s   i(j		
jc                 
   SS K n U R                  " 5        n[        U5      nSSKJn  SS KnU" UR                  UR                  S9  SSKJ	n  SSK
Jn  SSKJnJn  U" U5        U" USS5        [        U5      nUR                  S	-  UR                   -  n	U	R#                  S
S
S9  U	S-  R#                  S
S
S9  U	S-  S-  R%                  SSS9  U	S-  R%                  UR                   SS9  UR                  S-  n
U
R'                  5       (       d  U
R)                  5       (       a;  U
R)                  5       (       a  U
R+                  5         OSS KnUR/                  U
5         [0        R2                  " X5         " S SU5      nU" 5       nSSKJn  U" S5       nU" X-5        S S S 5        U
R)                  5       (       a  U
R=                  5       nUR>                  nSnUU:H  nU(       d  [@        RB                  " SU4SUU45      S[D        RF                  " 5       ;   d  [@        RH                  " U5      (       a  [@        RJ                  " U5      OS[@        RJ                  " U5      [@        RJ                  " U5      S.-  nSSU0-  n[M        [@        RN                  " U5      5      eS =n=nnGOU
S-  nURP                  nU" 5       nU(       d  SS[D        RF                  " 5       ;   d  [@        RH                  " U5      (       a  [@        RJ                  " U5      OS[@        RJ                  " U5      [@        RJ                  " U5      S .-  n[M        [@        RN                  " U5      5      eS =nnURS                  SS9RU                  5       nUS:w  ac  [W        S!5        UR                  RQ                  5       (       a#  [W        UR                  RS                  SS95        O[W        S"5        [W        S#5        SnUU:H  nU(       d  [@        RB                  " SU4S$UU45      S%[D        RF                  " 5       ;   d  [@        RH                  " U5      (       a  [@        RJ                  " U5      OS%[@        RJ                  " U5      S&.-  nS'S(U0-  n[M        [@        RN                  " U5      5      eS =nnSS KnURY                  5         UR[                  S)5      n[]        UR^                  5       H  nURa                  U5        M     S S S 5        g ! [4         a    SS KnUR7                  X5         GNf = f! , (       d  f       GN= f! , (       d  f       g = f)*Nr   )setup_logging)levelr   )process_commands)rW   rY   
server_123rc   versionsTparentsexist_okr   zmain.pyzprint('running')zutf-8)encodingVERSIONcurrentc                  &    \ rS rSrS rS rS rSrg)2test_agent_self_update_command.<locals>.MockClienti	  c                    SS0 S./$ )Nr   zagent.update)idcommand_typer   r   )r   r   s     r   get_pending_commandsGtest_agent_self_update_command.<locals>.MockClient.get_pending_commands
  s    $2!  r   c           	         SSSSSSSSS	.$ r   r   )r   r   s     r   r   Atest_agent_self_update_command.<locals>.MockClient.fetch_manifest  s$    ()'&:&!#"#$:	 	r   c                v   SoAU:H  oU(       d  [         R                  " SU4SX45      S[        R                  " 5       ;   d  [         R                  " U5      (       a  [         R
                  " U5      OS[         R
                  " U5      S.-  nSSU0-  n[        [         R                  " U5      5      eS =pTUS   nS	oU	:H  oD(       do  [         R                  " SU4S
X45      [         R
                  " U5      [         R
                  " U	5      S.-  n
SSU
0-  n[        [         R                  " U5      5      eS =n=pIg )Nr   r!   z%(py0)s == %(py3)s
command_idr   r   r   r   	succeededr   r   r   rN   )r1   r8   r/   r0   r2   r3   r4   r5   )r   r  result_dictr   r:   r?   r   rD   r~   r@   rQ   rR   s               r   post_command_resultFtest_agent_self_update_command.<locals>.MockClient.post_command_result  s    %&&Q&&&&z&&&&&&z&&&&z&&&Q&&&&&&&"8,;;;;;;;,;;;,;;;;;;;;;;r   r   N)r   r   r   r   r  r   r!  r   r   r   r   r   r  	  s    
<r   r   )patchzsubprocess.Popenr   r!   )z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)stargetr)   r*   r   zBassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.is_file
}()
}version_file)r   r$   r%   z--- AGENT LOG ---zAgent log file does not exist!z--- END AGENT LOG ---r  version_valr   r   r   	wolfpanel)1r+   r,   r   loggerr  logging	agent_logDEBUGrp   r   command_runnerr
  rO   rW   rY   opt_dirr   mkdirr   exists
is_symlinkunlinkshutilrmtreer   symlinkOSErrorcopytreeunittest.mockr#  readlinkr7   r1   r8   r/   r0   r2   r3   r4   r5   rv   rs   rt   printshutdown	getLoggerlisthandlersremoveHandler)r+   r   r   r  r)  r   r
  rW   rY   current_version_dircurrent_linkr2  r   r   r#  
mock_popenr$  r?   r;   r@   rD   rB   r%  rQ   r&  r:   r   root_loggerhandlers                                r   test_agent_self_update_commandrD     s   		$	$	&#C (cmm7==9(3;C#|-AB C  "kkJ69J9JJ!!$!>	u	$++D4+H	u	$y	0<<=OZa<b	y	(44S5F5FQX4Y{{Y.  L$;$;$=$=&&((##%l+	?JJ*9
	< 	<0 '%&*S) ' ""$$!**,F;;)');')))));'))))))6))))6)));)))')))))))')3L'')')))))))))<))))<)))'))))))))))&00'0BHHJKg%)*==((**#--1171CD:;-."));')))));'))))));))));)))'))))))) 	''4K001G%%g. 2o 
'	&B  	?OO/>	?< '& 
'	&sI   ET6S>5 T6	T$MT6>T!T6 T!!T6$
T3	.T66
Uc                 h   SSK Jn   So" U5      nSo2U:H  oD(       d  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=n=pCS
o" U5      nSo2U:H  oD(       d  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=n=pCSo" U5      nSo2U:H  oD(       d  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=n=pCSo" U5      nSo2U:H  oD(       d  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=n=pCg )Nr   )escape_mysql_stringmy_passr!   r   rF  r#   r&   r'   zmy'passzmy''passzmy\passzmy\\passzmy\'passz
my\\''pass)
actions.databaserF  r1   r8   r/   r0   r2   r3   r4   r5   )rF  r?   r@   r<   rA   rB   rC   s          r   test_escape_mysql_stringrI  ?  s   4(6y)6Y6Y66666)6666666666666y666)666Y6666666(7y)7Z7Z77777)7777777777777y777)777Z7777777):z*:l:l:::::*:::::::::::::z:::*:::l:::::::*={+=~=~=====+============={===+===~=======r   c                    SSK Jn   SS Kn[        R                  " 5        nU[
        R                  S'   [        U5      S-  S-  S-  nUR                  SSS9  [        U5      o@" U5      n[        U5      oeU:H  ow(       Gd  [        R                  " S	U4S
XV45      S[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  nSSU0-  n	[!        [        R"                  " U	5      5      eS =n=n=pv[        U5      S-  n
UR%                  [&        5         U " [        U
5      5        S S S 5        [        U5      S-  S-  S-  S-  S-  S-  nUR%                  [&        5         U " [        U5      5        S S S 5        S S S 5        g ! , (       d  f       Nc= f! , (       d  f       N(= f! , (       d  f       g = f)Nr   )_verify_safe_pathr   varwwwsite1Tr  r!   )zn%(py6)s
{%(py6)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
})
} == %(py11)s
{%(py11)s = %(py8)s(%(py9)s)
}rK  r   
valid_path)r   r   r$   r%   rN   r   r'   ro   zassert %(py13)spy13etcz..)actions.sftprK  pytestr+   r,   r   r   r   r.  r   r1   r8   r/   r0   r2   r3   r4   r5   raisesPermissionError)rK  rS  r   rO  r@   rA   r   rx   r   @py_format14invalid_pathtraversal_paths               r   test_sftp_directory_validationrY  G  s   .		$	$	&#+.

'( #Y&.8
5!$ZD 1DS_D_DDDDD1DDDDDD DDDD DDDDDDDDDDDDDDDDZDDDDZDDDDDD1DDDDDDSDDDDSDDDDDDDDDDDDD_DDDDDDD Cy5(]]?+c,/0 , cU*U2W<tCdJUR]]?+c.12 , 
'	& ,+
 ,+ 
'	&s<   JM5L$:ML5M$
L2	.M5
M	?M
Mc                 0   [         R                  " 5        n [        U 5      nUR                  nSo2U:H  oD(       d  [        R
                  " SU4SX#45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pCUR                  nSo2U:H  oD(       d  [        R
                  " SU4S	X#45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pCUR                  nS
o2U:H  oD(       d  [        R
                  " SU4SX#45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pCUR                  nSo2U:H  oD(       d  [        R
                  " SU4SX#45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pCS S S 5        g ! , (       d  f       g = f)Nr(   r!   )z6%(py2)s
{%(py2)s = %(py0)s.update_timeout
} == %(py5)sr   r)   r*   r      )z8%(py2)s
{%(py2)s = %(py0)s.backup_retention
} == %(py5)s   )z8%(py2)s
{%(py2)s = %(py0)s.update_retention
} == %(py5)s   )z8%(py2)s
{%(py2)s = %(py0)s.download_timeout
} == %(py5)s)r+   r,   r   update_timeoutr1   r8   r/   r0   r2   r3   r4   r5   backup_retentionupdate_retentiondownload_timeout)r   r   r?   r;   r@   rD   rB   s          r   test_update_configurationsrb  ]  s   		$	$	&#C !!'R'R'''''!''''''s''''s'''!'''R'''''''##(q(q(((((#((((((s((((s(((#(((q(((((((##(q(q(((((#((((((s((((s(((#(((q(((((((##)r)r)))))#))))))s))))s)))#)))r))))))) 
'	&	&s   M(N
Nc            	     ,   SSK Jn   SS K nSS Kn[        R                  " 5        nUR
                  R                  nUR
                  R                  nX1R
                  l        [        R                  R                  [        R                  R                  USSS5      5      UR
                  l        U[        R                  S'   [        U5      n[        U5      S-  S-  S-  nUR                  S	S	S
9  US-  R!                  S5        S[        R                  S'   [        U5      n SS KnU " S[%        U5      S	SS.5      n	U	S   n
S	oUL o(       do  [&        R(                  " SU4SX45      [&        R*                  " U
5      [&        R*                  " U5      S.-  nSSU0-  n[-        [&        R.                  " U5      5      eS =n
=pUR1                  S5        U " S[%        U5      S	SS.5      nUS   n
S	oUL o(       do  [&        R(                  " SU4SX45      [&        R*                  " U
5      [&        R*                  " U5      S.-  nSSU0-  n[-        [&        R.                  " U5      5      eS =n
=pUR1                  S5        U " S[%        U5      S	SS.5      nUS   n
S	oUL o(       do  [&        R(                  " SU4SX45      [&        R*                  " U
5      [&        R*                  " U5      S.-  nSSU0-  n[-        [&        R.                  " U5      5      eS =n
=p[        U5      S-  S-  S-  S-  nUR3                  5        Vs/ sH'  nUR4                  R7                  S5      (       d  M%  UPM)     nn[9        U5      nSnUU:H  nU(       Gd  [&        R(                  " SU4SUU45      S[:        R<                  " 5       ;   d  [&        R>                  " [8        5      (       a  [&        R*                  " [8        5      OSS[:        R<                  " 5       ;   d  [&        R>                  " U5      (       a  [&        R*                  " U5      OS[&        R*                  " U5      [&        R*                  " U5      S.-  nS S!U0-  n[-        [&        R.                  " U5      5      eS =n=nn[        R                  nUR@                  oS"   nU" U5      nU(       + nU(       d  S#S$[:        R<                  " 5       ;   d  [&        R>                  " [        5      (       a  [&        R*                  " [        5      OS$[&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      S%.-  n[-        [&        R.                  " U5      5      eS =n=n=n=nn[        R                  nUR@                  oS"   nU" U5      nU(       d  S&S$[:        R<                  " 5       ;   d  [&        R>                  " [        5      (       a  [&        R*                  " [        5      OS$[&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      S%.-  n[-        [&        R.                  " U5      5      eS =n=n=nn[        R                  nUR@                  nUS"   nU" U5      nU(       d  S&S$[:        R<                  " 5       ;   d  [&        R>                  " [        5      (       a  [&        R*                  " [        5      OS$[&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      [&        R*                  " U5      S%.-  n[-        [&        R.                  " U5      5      eS =n=n=nnXAR
                  l        XQR
                  l         S S S 5        g s  snf ! XAR
                  l        XQR
                  l        f = f! , (       d  f       g = f)'Nr   )handle_backup_createrL  backupsr'  r   rM  mysiteTr  z
index.htmlcontent2WOLFPANEL_BACKUP_RETENTIONz
mysite.comF)domaindocrootinclude_files
include_dbr   r   r  r   r   rN   g?z.tar.gzr  r!   rd   r   filesre   rf   r   backup_pathzfassert not %(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.exists
}(%(py6)s)
}r   )r   r$   r%   rN   r   zbassert %(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.exists
}(%(py6)s)
})!actions.backuprd  r2  r+   r,   backupDEV_HOMEBACKUP_BASE_DIRr   rm   realpathjoinr   r   r   r.  r   timer   r1   r8   r3   r4   r5   sleepiterdirr7   endswithr   r/   r0   r2   r/  )rd  actionsr2  r   original_dev_homeoriginal_baser   rk  rv  res1r~   r@   r:   rQ   rR   res2res3
backup_dirprn  rA   r;   r}   r?   rx   r=   rC   s                              r   test_backup_retention_limitr  f  s0   3		$	$	&##NN3366 #&)+)9)9"'',,sES\^i:j)k&+.

'(C  s)e#e+h6dT2	<	++I6 47

/0C 	;'<CPWLko  @E  )F  GD	?*d*d*****?***?***d*******JJt'<CPWLko  @E  )F  GD	?*d*d*****?***?***d*******JJt'<CPWLko  @E  )F  GD	?*d*d*****?***?***d******* cU*Y6D|SJ * 2 2 4S 41	8RQ 4ES u:"":?"""":""""""3""""3""""""u""""u""":""""""""""ww:w~~:=&9:~&9::::::::::::r::::r:::w:::~:::&9:::::::::::7767>>6}"56>"56666666662666626667666>666"566666666667767>>6$}"56>"56666666662666626667666>666"56666666666&7NN#-:NN*_ 
'	&J T '8NN#-:NN*_ 
'	&s>   C?`$H_ #_(_.Q_ 1 `_  "``
`__main__test_r   zPASS zFAIL )r   r   )6__doc__
__future__r   builtinsr/   _pytest.assertion.rewrite	assertionrewriter1   r   sysr+   pathlibr   rm   insertr   __file__resolver  r   rE   rS   r   r   r   r   r   r   r   r   r  rD  rI  rY  rb  r  r   	tracebacksortedglobalsitemsr.   funcsfailuresfunc__code__co_varnamesr,   r   r9  	Exception	print_excexit)kvs   00r   <module>r     s   #   	 
   3tH~--/77:UBC D',!N,Q3B+";*!07.tZ/z>3,*3;l z!')//"34N441W8MQ4NEH	"T]]666002ccO 32 E$--)*  HH(Q"%  O 32
  	"MHE$--)*!	"s6   E<*E<<+F'F6%F
F	F1GG