§
    Q¿jÉ#  ã                  óî   — d Z ddl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	Z
ddlZ
ddlZ
ddlZddlmZmZmZmZ ddlmZmZ ddlmZ ddlmZ  ej        d¬	¦  «        dd„¦   «         Z G d„ d¦  «        ZdS )a  
Challenger M3 Empirical Stress Test: /api/map Endpoint and Biome Pipeline.
Validates:
1. All 30 biome integer queries (biome=1..30) return HTTP 200 with byte[3] == biome_code.
2. All 30 biome style string queries (biome=STY_01..STY_30) return HTTP 200 with expected byte[3].
3. Legacy biome name queries return HTTP 200.
4. Canonical zone resolution with and without biome override.
5. Boundary, invalid, malformed, and adversarial inputs (fuzzing).
6. Multi-threaded concurrent request performance and thread safety.
é    )ÚannotationsN)Ú	GeneratorÚDictÚAnyÚList)Úlist_stylesÚget_map_style)Ú
MAP_BIOMES)ÚFreeExileHTTPRequestHandlerÚmodule)ÚscopeÚreturnúGenerator[str, None, None]c               #  óL  K  —  G d„ dt           j        t           j        ¦  «        }  | dt          ¦  «        }|j        d         }t          j        |j        d¬¦  «        }|                     ¦   «          d|› �}|V — | 	                    ¦   «          | 
                    ¦   «          d S )Nc                  ó   — e Zd ZdZdZdS )ú#api_server.<locals>.ThreadingServerTN)Ú__name__Ú
__module__Ú__qualname__Údaemon_threadsÚallow_reuse_address© ó    úBC:\Projects\FreeExile\tests\unit\test_challenger_api_map_stress.pyÚThreadingServerr      s   € € € € € ØˆØ"ÐÐÐr   r   )z	127.0.0.1r   é   T)ÚtargetÚdaemonzhttp://127.0.0.1:)ÚsocketserverÚThreadingMixInÚ	TCPServerr   Úserver_addressÚ	threadingÚThreadÚserve_foreverÚstartÚshutdownÚserver_close)r   ÚserverÚportÚtÚbase_urls        r   Ú
api_serverr-      s½   è è € ð#ð #ð #ð #ð #�,Ô5µ|Ô7Mñ #ô #ð #ð ˆ_Ð-Õ/JÑKÔK€FØÔ  Ô#€DÝÔ Ô 4¸TÐBÑBÔB€AØ‡G‚G�I„I€IØ) 4Ð)Ð)€HØ
€N€N€NØ
‡O‚OÑÔÐØ
×ÒÑÔÐÐÐr   c                  óZ   — e Zd ZdZdd„Zdd„Zdd„Zdd	„Zdd
„Zdd„Z	dd„Z
dd„Zdd„ZdS )ÚTestApiMapEndpointEmpiricalzGEmpirical verification of /api/map across all 30 biomes and edge cases.r-   Ústrr   ÚNonec                ó�  — t          dd¦  «        D �]3}|› d|dz  › d|› �}t          j                             |¦  «        }t          j                             |d¬¦  «        5 }|j        dk    sJ d	|› d
|j        › �¦   «         ‚|j                             d¦  «        dk    sJ ‚|                     ¦   «         }t          |¦  «        dk    sJ d|› �¦   «         ‚|dd…         dk    sJ d|› �¦   «         ‚|d         dk    sJ d|› �¦   «         ‚|d         |k    sJ d|› d
|d         › �¦   «         ‚	 ddd¦  «         n# 1 swxY w Y   �Œ5dS )zEEvery biome code from 1 to 30 must yield 200 and exact byte[3] match.r   é   ú*/api/map?zone_id=zone_tang_kiem_nhai&seed=é   ú&biome=é   ©ÚtimeoutéÈ   zExpected 200 for biome=ú, got zContent-Typezapplication/octet-streamé   zBody too small for biome=Né   ó   FEz Magic header mismatch for biome=zVersion mismatch for biome=é   zByte 3 mismatch: expected )
ÚrangeÚurllibÚrequestÚRequestÚurlopenÚstatusÚheadersÚgetÚreadÚlen)Úselfr-   ÚcodeÚurlÚreqÚrespÚbodys          r   Útest_all_30_integer_biomesz6TestApiMapEndpointEmpirical.test_all_30_integer_biomes0   s×  € å˜!˜R‘L”Lð 
	[ñ 
	[ˆDØÐcÐcÈ4ÐRTÉ9ÐcÐcÐ]aÐcÐcˆCÝ”.×(Ò(¨Ñ-Ô-ˆCÝ”×'Ò'¨°QÐ'Ñ7Ô7ð [¸4Ø”{ cÒ)Ð)Ð)Ð+^ÀTÐ+^Ð+^ÐQUÔQ\Ð+^Ð+^Ñ)Ô)Ð)Ø”|×'Ò'¨Ñ7Ô7Ð;UÒUÐUÐUÐUØ—y’y‘{”{�Ý˜4‘y”y 2’~�~�~Ð'IÀ4Ð'IÐ'I‘~”~�~Ø˜B˜Q˜B”x 5Ò(Ð(Ð(Ð*SÈTÐ*SÐ*SÑ(Ô(Ð(Ø˜A”w !’|�|�|Ð%IÀ4Ð%IÐ%I‘|”|�|Ø˜A”w $’��Ð(ZÀTÐ(ZÐ(ZÐQUÐVWÔQXÐ(ZÐ(Z‘”��ð[ð [ð [ñ [ô [ð [ð [ð [ð [ð [ð [øøøð [ð [ð [ð [ùð
	[ð 
	[s   Á!CD9Ä9D=	Å D=	c           
     ó
  — t          ¦   «         }t          |¦  «        dk    sJ ‚|D ]Ü}|› d|j        › �}t          j                             |¦  «        }t          j                             |d¬¦  «        5 }|j        dk    sJ d|j        › �¦   «         ‚|                     ¦   «         }|dd…         d	k    sJ ‚|d
         |j	        k    s#J d|j        › d|j	        › d|d
         › �¦   «         ‚	 ddd¦  «         n# 1 swxY w Y   ŒÝdS )zEQuerying by STY_ style ID string must return 200 and correct byte[3].é   z4/api/map?zone_id=zone_tang_kiem_nhai&seed=999&biome=r7   r8   r:   zFailed for style Nr=   r>   r?   zStyle z expected byte 3 to be r;   )
r   rI   Ústyle_idrA   rB   rC   rD   rE   rH   Ú
biome_code)rJ   r-   ÚstylesÚstylerL   rM   rN   rO   s           r   Útest_all_30_style_id_stringsz8TestApiMapEndpointEmpirical.test_all_30_style_id_strings>   sk  € å‘”ˆÝ�6‰{Œ{˜bÒ Ð Ð Ð Øð 		ð 		ˆEØÐeÐeÐUZÔUcÐeÐeˆCÝ”.×(Ò(¨Ñ-Ô-ˆCÝ”×'Ò'¨°QÐ'Ñ7Ô7ð ¸4Ø”{ cÒ)Ð)Ð)Ð+O¸u¼~Ð+OÐ+OÑ)Ô)Ð)Ø—y’y‘{”{�Ø˜B˜Q˜B”x 5Ò(Ð(Ð(Ð(Ø˜A”w %Ô"2Ò2Ð2Ð2Øe˜Uœ^ÐeÐeÀEÔDTÐeÐeÐ\`ÐabÔ\cÐeÐeñ 3Ô2Ð2Ð2ð	ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð øð		ð 		s   Á4A6C7Ã7C;	Ã>C;	c           
     ó–  — ddddddœ}|                      ¦   «         D ]«\  }}|› d|› �}t          j                             |¦  «        }t          j                             |d¬¦  «        5 }|j        d	k    sJ ‚|                     ¦   «         }|d         |k    sJ d
|› d|› d|d         › �¦   «         ‚	 ddd¦  «         n# 1 swxY w Y   Œ¬dS )zCLegacy biome names (codes 1-5) must return 200 and match codes 1-5.r   r=   r?   é   r7   )ÚBLEACHED_BONE_CANYONÚSAVAGE_MANGROVE_SWAMPÚCRIMSON_BLOOD_FORESTÚOUTCAST_MINE_SHAFTSÚCORRUPTED_FIEND_RUINSz4/api/map?zone_id=zone_tang_kiem_nhai&seed=123&biome=r8   r:   zLegacy biome z
 expected r;   N)ÚitemsrA   rB   rC   rD   rE   rH   )	rJ   r-   ÚlegacyÚb_nameÚb_coderL   rM   rN   rO   s	            r   Útest_legacy_biome_namesz3TestApiMapEndpointEmpirical.test_legacy_biome_namesM   sQ  € ð %&Ø%&Ø$%Ø#$Ø%&ð
ð 
ˆð %Ÿlšl™nœnð 	dð 	d‰NˆF�FØÐ]Ð]ÐU[Ð]Ð]ˆCÝ”.×(Ò(¨Ñ-Ô-ˆCÝ”×'Ò'¨°QÐ'Ñ7Ô7ð d¸4Ø”{ cÒ)Ð)Ð)Ð)Ø—y’y‘{”{�Ø˜A”w &Ò(Ð(Ð(Ð*c¸&Ð*cÐ*cÈFÐ*cÐ*cÐZ^Ð_`ÔZaÐ*cÐ*cÑ(Ô(Ð(Ð(ðdð dð dñ dô dð dð dð dð dð dð døøøð dð dð dð døð	dð 	ds   Á)AB=Â=C	ÃC	c           
     óŒ  — g d¢}|D ]¼\  }}|› d|› d�}t           j                             |¦  «        }t           j                             |d¬¦  «        5 }|j        dk    sJ ‚|                     ¦   «         }|dd…         d	k    sJ ‚|d
         |k    sJ d|› d|› d|d
         › �¦   «         ‚	 ddd¦  «         n# 1 swxY w Y   Œ½dS )zHEvery canonical zone without ?biome= parameter returns valid binary map.)	)Úzone_tang_kiem_nhair   )Úzone_ancient_sword_barrowé   )Úzone_boundless_sandstormé   )Úzone_blood_scale_ruinsr?   )Úzone_five_elements_altaré   )Úzone_abyssal_ice_pondr5   )Úzone_infinite_blood_rifté   )Úzone_purgatory_lava_caverné   )Úzone_boundless_celestial_palacerR   z/api/map?zone_id=z&seed=42r7   r8   r:   Nr=   r>   r?   zZone z expected canonical biome r;   ©rA   rB   rC   rD   rE   rH   )	rJ   r-   Úcanonical_zonesÚzidÚexpected_coderL   rM   rN   rO   s	            r   Ú'test_all_canonical_zones_default_biomeszCTestApiMapEndpointEmpirical.test_all_canonical_zones_default_biomes^   sZ  € ð

ð 

ð 

ˆð #2ð 	wð 	wÑˆC�ØÐ?Ð?°#Ð?Ð?Ð?ˆCÝ”.×(Ò(¨Ñ-Ô-ˆCÝ”×'Ò'¨°QÐ'Ñ7Ô7ð w¸4Ø”{ cÒ)Ð)Ð)Ð)Ø—y’y‘{”{�Ø˜B˜Q˜B”x 5Ò(Ð(Ð(Ð(Ø˜A”w -Ò/Ð/Ð/Ð1v¸Ð1vÐ1vÐXeÐ1vÐ1vÐmqÐrsÔmtÐ1vÐ1vÑ/Ô/Ð/Ð/ð	wð wð wñ wô wð wð wð wð wð wð wøøøð wð wð wð wøð	wð 	ws   ÁAB8Â8B<	Â?B<	c                óÐ  — dD ]â}|› d|› �}t           j                             |¦  «        }	 t           j                             |d¬¦  «        5 }|j        dk    sJ ‚|                     ¦   «         }|dd…         dk    sJ ‚|d	         d
k    sJ d|› d|d	         › �¦   «         ‚	 ddd¦  «         n# 1 swxY w Y   Œ·# t           j        j        $ r}|j        dv sJ ‚Y d}~ŒÛd}~ww xY wdS )z7Inspect server behavior on out-of-range integer biomes.)r   r3   iç  éûÿÿÿú3/api/map?zone_id=zone_tang_kiem_nhai&seed=42&biome=r7   r8   r:   Nr=   r>   r?   r   z)Expected fallback to code 1 for bad code r;   ©i�  éô  )	rA   rB   rC   rD   rE   rH   ÚerrorÚ	HTTPErrorrK   )rJ   r-   Úbad_coderL   rM   rN   rO   Úes           r   Ú)test_out_of_range_integer_biomes_behaviorzETestApiMapEndpointEmpirical.test_out_of_range_integer_biomes_behaviort   s|  € ð )ð 	,ð 	,ˆHØÐ^Ð^ÐT\Ð^Ð^ˆCÝ”.×(Ò(¨Ñ-Ô-ˆCð	,Ý”^×+Ò+¨C¸Ð+Ñ;Ô;ð o¸tØœ;¨#Ò-Ð-Ð-Ð-ØŸ9š9™;œ;�DØ   œ8 uÒ,Ð,Ð,Ð,à œ7 aš<˜<˜<Ð)nÐU]Ð)nÐ)nÐeiÐjkÔelÐ)nÐ)n™<œ<˜<˜<ðoð oð oñ oô oð oð oð oð oð oð oøøøð oð oð oð oøøõ ”<Ô)ð ,ð ,ð ,à”v Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+øøøøð,øøøð	,ð 	,s<   ¬!B:ÁAB.Â"B:Â.B2	Â2B:Â5B2	Â6B:Â:C#ÃCÃC#c                óÄ  — |› d�}t           j                             |¦  «        }t          j        t           j        j        ¦  «        5 }t           j                             |d¬¦  «         ddd¦  «         n# 1 swxY w Y   |j        }|j	        dk    sJ ‚t          j        |                     ¦   «                              d¦  «        ¦  «        }d|v sJ ‚d|d         v sJ ‚dS )	zLUnknown string biome produces 500 JSON response rather than crashing server.zL/api/map?zone_id=zone_tang_kiem_nhai&seed=42&biome=INVALID_NONEXISTENT_BIOMEr7   r8   Nr|   úutf-8r}   zUnknown biome_id©rA   rB   rC   ÚpytestÚraisesr}   r~   rD   ÚvaluerK   ÚjsonÚloadsrH   Údecode©rJ   r-   rL   rM   Úexc_infoÚerrÚdatas          r   Ú0test_unknown_string_biome_returns_500_error_jsonzLTestApiMapEndpointEmpirical.test_unknown_string_biome_returns_500_error_json…   s
  € àÐiÐiÐiˆÝŒn×$Ò$ SÑ)Ô)ˆÝŒ]�6œ<Ô1Ñ2Ô2ð 	3°hÝŒN×"Ò" 3°Ð"Ñ2Ô2Ð2ð	3ð 	3ð 	3ñ 	3ô 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3øøøð 	3ð 	3ð 	3ð 	3àŒnˆØŒx˜3ŠˆˆˆÝŒz˜#Ÿ(š(™*œ*×+Ò+¨GÑ4Ô4Ñ5Ô5ˆØ˜$ˆˆˆˆØ! T¨'¤]Ð2Ð2Ð2Ð2Ð2Ð2ó   Á"A6Á6A:Á=A:c                ó¬  — |› d�}t           j                             |¦  «        }t          j        t           j        j        ¦  «        5 }t           j                             |d¬¦  «         ddd¦  «         n# 1 swxY w Y   |j        }|j	        dk    sJ ‚t          j        |                     ¦   «                              d¦  «        ¦  «        }d|v sJ ‚dS )zBNon-integer seed returns 500 JSON response with error explanation.z6/api/map?zone_id=zone_tang_kiem_nhai&seed=not_a_numberr7   r8   Nr|   rƒ   r}   r„   r‹   s          r   Útest_malformed_seed_parameterz9TestApiMapEndpointEmpirical.test_malformed_seed_parameter‘   só   € àÐSÐSÐSˆÝŒn×$Ò$ SÑ)Ô)ˆÝŒ]�6œ<Ô1Ñ2Ô2ð 	3°hÝŒN×"Ò" 3°Ð"Ñ2Ô2Ð2ð	3ð 	3ð 	3ñ 	3ô 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3øøøð 	3ð 	3ð 	3ð 	3àŒnˆØŒx˜3ŠˆˆˆÝŒz˜#Ÿ(š(™*œ*×+Ò+¨GÑ4Ô4Ñ5Ô5ˆØ˜$ˆˆˆˆˆˆr�   c                ó  — g d¢}|D ]ú}t           j                             |¦  «        }|› d|› �}t           j                             |¦  «        }	 t           j                             |d¬¦  «        5 }|j        dk    sJ ‚	 ddd¦  «         n# 1 swxY w Y   Œ�# t           j        j        $ rT}|j	        dv sJ ‚t          j        |                     ¦   «                              d¦  «        ¦  «        }	d	|	v sJ ‚Y d}~Œód}~ww xY wdS )
zJVerify adversarial payloads do not cause code injection or server crashes.)z<script>alert(1)</script>z../../../../etc/passwdzSELECT * FROM map_stylesz	%00%ff%ferz   r7   r8   r:   Nr{   rƒ   r}   )rA   ÚparseÚquoterB   rC   rD   rE   r}   r~   rK   rˆ   r‰   rH   rŠ   )
rJ   r-   Úadversarial_payloadsÚpayloadÚencodedrL   rM   rN   r€   rŽ   s
             r   Ú$test_xss_and_path_traversal_payloadsz@TestApiMapEndpointEmpirical.test_xss_and_path_traversal_payloadsœ   sg  € ð 
ð  
ð  
Ðð ,ð 
	'ð 
	'ˆGÝ”l×(Ò(¨Ñ1Ô1ˆGØÐ]Ð]ÐT[Ð]Ð]ˆCÝ”.×(Ò(¨Ñ-Ô-ˆCð'Ý”^×+Ò+¨C¸Ð+Ñ;Ô;ð .¸tØœ;¨#Ò-Ð-Ð-Ð-Ð-ð.ð .ð .ñ .ô .ð .ð .ð .ð .ð .ð .øøøð .ð .ð .ð .øøå”<Ô)ð 'ð 'ð 'Ø”v Ð+Ð+Ð+Ð+Ý”z !§&¢&¡(¤(§/¢/°'Ñ":Ô":Ñ;Ô;�Ø $���������øøøøð'øøøð
	'ð 
	's=   Á!BÁ0BÁ?BÂB	ÂBÂB	ÂBÂC?Â+A
C:Ã:C?c                ót  ‡‡‡— dˆfd„Št           j                             d¬¦  «        5 Šˆˆfd„t          dd	¦  «        D ¦   «         }d
„ t           j                             |¦  «        D ¦   «         }ddd¦  «         n# 1 swxY w Y   t          |¦  «        dk    sJ ‚t          d„ |D ¦   «         ¦  «        sJ ‚dS )zF50 concurrent requests across all 30 biomes execute with 100% success.rK   Úintr   c                ó6  •— ‰› d| dz  › d| dz
  dz  dz   › �}t           j                             |¦  «        }t           j                             |d¬¦  «        5 }|j        dk    sJ ‚|                     ¦   «         }|d	         cd d d ¦  «         S # 1 swxY w Y   d S )
Nr4   é   r6   r   rR   é
   r8   r:   r?   rs   )rK   rL   rM   rN   Úbr-   s        €r   Úfetch_biomezTTestApiMapEndpointEmpirical.test_concurrent_requests_throughput.<locals>.fetch_biome²   sî   ø€ ØÐsÐsÈ4ÐRSÉ8ÐsÐsÐ^bÐefÑ^fÐjlÑ]lÐpqÑ\qÐsÐsˆCÝ”.×(Ò(¨Ñ-Ô-ˆCÝ”×'Ò'¨°RÐ'Ñ8Ô8ð ¸DØ”{ cÒ)Ð)Ð)Ð)Ø—I’I‘K”K�Ø˜”tðð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð s   Á)BÂBÂBé   )Úmax_workersc                ó<   •— g | ]}‰                      ‰|¦  «        ‘ŒS r   )Úsubmit)Ú.0ÚiÚexecutorr    s     €€r   ú
<listcomp>zSTestApiMapEndpointEmpirical.test_concurrent_requests_throughput.<locals>.<listcomp>»   s'   ø€ ÐMÐMÐM¸1�x—’ {°AÑ6Ô6ÐMÐMÐMr   r   é3   c                ó6   — g | ]}|                      ¦   «         ‘ŒS r   )Úresult)r¥   Úfs     r   r¨   zSTestApiMapEndpointEmpirical.test_concurrent_requests_throughput.<locals>.<listcomp>¼   s    € ÐTÐTÐT a�q—x’x‘z”zÐTÐTÐTr   Né2   c              3  ó6   K  — | ]}d |cxk    odk    nc V — ŒdS )r   rR   Nr   )r¥   Úrs     r   ú	<genexpr>zRTestApiMapEndpointEmpirical.test_concurrent_requests_throughput.<locals>.<genexpr>¿   s6   è è € Ð1Ð1 A�1˜�<�<’<�<˜R’<�<�<�<Ð1Ð1Ð1Ð1Ð1Ð1r   )rK   r›   r   r›   )Ú
concurrentÚfuturesÚThreadPoolExecutorr@   Úas_completedrI   Úall)rJ   r-   r²   Úresultsr§   r    s    `  @@r   Ú#test_concurrent_requests_throughputz?TestApiMapEndpointEmpirical.test_concurrent_requests_throughput°   s+  øøø€ ð	ð 	ð 	ð 	ð 	ð 	õ Ô×2Ò2¸qÐ2ÑAÔAð 	UÀXØMÐMÐMÐMÐMÅÀaÈÁÄÐMÑMÔMˆGØTÐT­:Ô+=×+JÒ+JÈ7Ñ+SÔ+SÐTÑTÔTˆGð	Uð 	Uð 	Uñ 	Uô 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uøøøð 	Uð 	Uð 	Uð 	Uõ �7‰|Œ|˜rÒ!Ð!Ð!Ð!ÝÐ1Ð1¨Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1s   ªAA=Á=BÂBN)r-   r0   r   r1   )r   r   r   Ú__doc__rP   rW   rc   rw   r�   r�   r’   r™   r·   r   r   r   r/   r/   -   sÚ   € € € € € ØQÐQð[ð [ð [ð [ðð ð ð ðdð dð dð dð"wð wð wð wð,,ð ,ð ,ð ,ð"
3ð 
3ð 
3ð 
3ð	ð 	ð 	ð 	ð'ð 'ð 'ð 'ð(2ð 2ð 2ð 2ð 2ð 2r   r/   )r   r   )r¸   Ú
__future__r   Úconcurrent.futuresr±   rˆ   r   Ústructr#   Úurllib.parserA   Úurllib.requestÚurllib.errorr…   Útypingr   r   r   r   Úserver.world.map_style_catalogr   r	   Úserver.world.map_biome_catalogr
   Útools.serve_webappr   Úfixturer-   r/   r   r   r   ú<module>rÄ      sR  ðð	ð 	ð #Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -à EÐ EÐ EÐ EÐ EÐ EÐ EÐ EØ 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø :Ð :Ð :Ð :Ð :Ð :ð €„�hÐÑÔðð ð ñ  ÔððR2ð R2ð R2ð R2ð R2ñ R2ô R2ð R2ð R2ð R2r   