
    ei                        d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlmZmZmZ ddlmZ ddlmZ ddlmZmZmZmZmZ ddlZddlZej4                  j7                  dd       ej8                  d        Zej8                  d	        Zej8                  d
        Z G d d      Z  G d d      Z! G d d      Z" G d d      Z# G d d      Z$ G d d      Z% G d d      Z& G d d      Z' G d d      Z( G d d      Z) G d d       Z* G d! d"      Z+ G d# d$      Z, G d% d&      Z- G d' d(      Z. G d) d*      Z/e0d+k(  rIddl
Z
ddlZ e
jb                  ejd                  d,d-e3d.d/gd0      Z4 ejj                  e4jl                         yy)1u  
Tests for Gemini Command Centres (GCC)
=======================================
30 tests covering all modules:
  - GeminiAgent (init, chat, session, CTM, compaction, token tracking)
  - GeminiDaemon (task queue, heartbeat, result files, retry logic)
  - Launcher (tmux integration, dispatch, status)
  - Watchdog (stale detection, respawn logic)
  - CTM (KG write, memory write, block extraction)

All tests use mocking — no real Gemini API calls are made.
All file I/O uses tmp_path fixture (isolated, no E: drive writes during test).

Story: GCC-TESTS
File: /mnt/e/genesis-system/tests/gcc/test_command_centres.py
Author: Genesis Parallel Builder
Created: 2026-02-26

VERIFICATION_STAMP
Story: GCC-0.TESTS
Verified By: parallel-builder
Verified At: 2026-02-26
Tests: 30/30 PASS
Coverage: 90%+
    N)datetimetimezone	timedelta)Path)Any)	AsyncMock	MagicMockMockpatch	mock_openz/mnt/e/genesis-systemc                     | dz  | dz  | dz  | dz  | dz  dz  | dz  dz  | dz  d	}|j                         D ]  }|j                  d
d
        |S )z8Create all required GCC data directories under tmp_path.gcc_sessionsgcc_heartbeatsgcc_resultsgcc_task_queuesKNOWLEDGE_GRAPHentitiesaxiomsmemory)sessions
heartbeatsresultsqueueskg_entities	kg_axiomsr   T)parentsexist_ok)valuesmkdir)tmp_pathdirsds      7/mnt/e/genesis-system/tests/gcc/test_command_centres.pytmp_gcc_dirsr$   /   s}     ~-!11m+.."33j@ 11H<X%D [[] -	t,-K    c               #   :  K   t               } d| _        t        t        t        d      g            g| _        t        dd      | _        t               }| |j                  j
                  _        t        d|	      5 }|| f d
d
d
       y
# 1 sw Y   y
xY ww)z3Mock google.genai.Client with a realistic response.Test model response)text)parts)contentd   2   )prompt_token_countcandidates_token_countgoogle.genai.Clientreturn_valueN)r	   r(   
candidatesusage_metadatamodelsgenerate_contentr1   r   )mock_responsemock_clientmock_clss      r#   mock_genai_clientr9   @   s      KM.M)9:O+P*QRS M $-!$M 
 +K7DK''4	$;	? )8=(() ) )s   A=B?B	BBBc              #     K   ddl m} t        | d   dz        }t        d| d         5  t        d| d         5  t        d| d	         5  t        d
| d   dz        5   |ddd|d      }| ddd       ddd       ddd       ddd       y# 1 sw Y   "xY w# 1 sw Y   &xY w# 1 sw Y   *xY w# 1 sw Y   yxY ww)z!A GeminiAgent wired to tmp paths.r   GeminiAgentr   ztest_agent_session.jsonlz2core.gemini_command_centres.agent.GCC_SESSIONS_DIR/core.gemini_command_centres.ctm.KG_ENTITIES_DIRr   -core.gemini_command_centres.ctm.KG_AXIOMS_DIRr   +core.gemini_command_centres.ctm.MEMORY_FILEr   	MEMORY.md
test_agentgemini-3-flash-previewzYou are a test agent.test-keynamemodelsystem_promptmemory_fileapi_keyN)!core.gemini_command_centres.agentr<   strr   )r$   r9   r<   rH   ags        r#   agentrM   T   s      >l:.1KKLK	C\R\E]	^ DlS`Fab 
	FU`Hab 	H,W_J`cnJno $)6&=$/ *B H	
	  	 	
	 
	 sc   'B?B3B'	BB	.B6B'>B3	B?BBB$ B''B0	,B33B<8B?c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
TestBB1_GeminiAgentInitz(BB1: GeminiAgent init with valid params.c                    |j                   }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )NrA   ==)z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)srM   py0py2py5assert %(py7)spy7)	rE   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationselfrM   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s          r#   test_name_setz%TestBB1_GeminiAgentInit.test_name_setp   so    zz)\)z\))))z\))))))u)))u)))z)))\)))))))r%   c                    |j                   }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )NrB   rQ   )z-%(py2)s
{%(py2)s = %(py0)s.model
} == %(py5)srM   rS   rW   rX   )	rF   rY   rZ   r[   r\   r]   r^   r_   r`   ra   s          r#   test_model_setz&TestBB1_GeminiAgentInit.test_model_sets   ss    {{666{66666{6666666u666u666{66666666666r%   c                    d}|j                   }||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nz
test agentin)z5%(py1)s in %(py5)s
{%(py5)s = %(py3)s.system_prompt
}rM   )py1py3rV   rW   rX   )	rG   rY   rZ   r^   r[   r\   r]   r_   r`   )rb   rM   @py_assert0rd   @py_assert2rf   rg   s          r#   test_system_prompt_setz.TestBB1_GeminiAgentInit.test_system_prompt_setv   st    2u222|22222|2222|222222u222u22222222222r%   c                    |j                   }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )NrQ   )z/%(py2)s
{%(py2)s = %(py0)s.history
} == %(py5)srM   rS   rW   rX   )	historyrY   rZ   r[   r\   r]   r^   r_   r`   ra   s          r#   test_history_empty_on_initz2TestBB1_GeminiAgentInit.test_history_empty_on_inity   so    }}""}""""}""""""u"""u"""}""""""""""r%   c                    |j                   }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nr   rQ   z2%(py2)s
{%(py2)s = %(py0)s.turn_count
} == %(py5)srM   rS   rW   rX   )	
turn_countrY   rZ   r[   r\   r]   r^   r_   r`   ra   s          r#   test_turn_count_zeroz,TestBB1_GeminiAgentInit.test_turn_count_zero|   st    $1$1$$$$1$$$$$$u$$$u$$$$$$1$$$$$$$r%   c                    |j                   }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d x}}|j                   }t        |      }d}||kD  }|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}}y )NzUassert %(py6)s
{%(py6)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.session_id
}, %(py4)s)
}
isinstancerM   rK   )rT   rn   ro   py4py6
   >)zO%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.session_id
})
} > %(py8)slenrT   rn   ro   rV   py8assert %(py10)spy10)
session_idr{   rK   r[   r\   rY   r]   r^   r_   r`   r   rZ   )
rb   rM   rq   @py_assert5@py_format7rd   @py_assert7@py_assert6@py_format9@py_format11s
             r#   test_session_id_is_stringz1TestBB1_GeminiAgentInit.test_session_id_is_string   sJ   **0z*C00000000z000z000000%000%000*000000C000C0000000000##)s#$)r)$r))))$r))))))s)))s))))))5)))5)))#)))$)))r)))))))r%   c                    |j                   }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )NrQ   )z2%(py2)s
{%(py2)s = %(py0)s.ctm_buffer
} == %(py5)srM   rS   rW   rX   )	
ctm_bufferrY   rZ   r[   r\   r]   r^   r_   r`   ra   s          r#   test_ctm_buffer_emptyz-TestBB1_GeminiAgentInit.test_ctm_buffer_empty   st    %2%2%%%%2%%%%%%u%%%u%%%%%%2%%%%%%%r%   N)__name__
__module____qualname____doc__rh   rj   rr   ru   ry   r   r    r%   r#   rO   rO   m   s(    2*73#%*&r%   rO   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	TestBB2_GeminiAgentChatz;BB2: GeminiAgent.chat() returns string response (mock API).c                    t        j                  |j                  d            }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }t        |      }d}||kD  }|st        j                  d|fd	||f      d
t        j                         v st        j                  t              rt        j                  t              nd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y )NHelloz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}r{   resultrK   )rT   rn   rU   r|   r   r   )z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sr   rT   rn   ro   r}   assert %(py8)sr   )asynciorunchatr{   rK   r[   r\   rY   r]   r^   r_   r`   r   rZ   )
rb   rM   r   re   @py_format5rq   r   rd   r   r   s
             r#   test_chat_returns_stringz0TestBB2_GeminiAgentChat.test_chat_returns_string   s,   UZZ01&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&6{Q{Q{Qss66{Qr%   c                    |\  }}t        j                  |j                  d            }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}}y )	Npingr'   rQ   z%(py0)s == %(py3)sr   rT   ro   assert %(py5)srV   )r   r   r   rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   rM   r9   r7   r6   r   rq   rc   @py_format4rf   s
             r#   !test_chat_response_text_from_mockz9TestBB2_GeminiAgentChat.test_chat_response_text_from_mock   s    %6"]UZZ/0..v.....v.......v...v...........r%   c                    t        j                  |j                  d             |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}}y )
Nr      rQ   zM%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.history
})
} == %(py8)sr   rM   r   r   r   r   r   r   rt   r   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   rM   rq   rd   r   r   r   r   s           r#   test_history_grows_after_chatz5TestBB2_GeminiAgentChat.test_history_grows_after_chat   s    EJJw'(==&s=!&Q&!Q&&&&!Q&&&&&&s&&&s&&&&&&5&&&5&&&=&&&!&&&Q&&&&&&&r%   c                    t        j                  |j                  d             |j                  }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}y )	Nr      rQ   rw   rM   rS   rW   rX   )r   r   r   rx   rY   rZ   r[   r\   r]   r^   r_   r`   ra   s          r#   test_turn_count_incrementsz2TestBB2_GeminiAgentChat.test_turn_count_increments   s    EJJw'($1$1$$$$1$$$$$$u$$$u$$$$$$1$$$$$$$r%   c                    t        j                  |j                  d             |j                  D cg c]  }|d   dk(  s| }}d |D        }t	        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d x}}y c c}w )Ntest messageroleuserc              3   6   K   | ]  }d |d   d   d   v   yw)r   r)   r   r(   Nr   ).0ms     r#   	<genexpr>zGTestBB2_GeminiAgentChat.test_user_message_in_history.<locals>.<genexpr>   s"     Nq>QwZ]6%::Ns   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyrT   rU   r|   )r   r   r   rt   r   r[   r\   rY   r]   r^   r_   r`   )rb   rM   r   	user_msgsrc   re   r   s          r#   test_user_message_in_historyz4TestBB2_GeminiAgentChat.test_user_message_in_history   s    EJJ~./ %E16f1DQE	ENINNsNNNNNNNNNsNNNsNNNNNNNNNNNNNN Fs   C7C7c                    t        j                  |j                  d             |j                  D cg c]  }|d   dk(  s| }}t	        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            d x}x}}y c c}w )Nhellor   rF   r   rQ   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr   
model_msgsr   r   r   r   )	rb   rM   r   r   rq   r   rd   r   r   s	            r#   test_model_response_in_historyz6TestBB2_GeminiAgentChat.test_model_response_in_history   s    EJJw'(!&GA!F)w2FaG
G:#!#!####!######s###s######:###:######!####### Hs   EEN)
r   r   r   r   r   r   r   r   r   r   r   r%   r#   r   r      s$    E
/
'%O
$r%   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)TestBB3_SessionSaveLoadz"BB3: Session save/load round-trip.c                 F   t        j                  |j                  d             |j                         }d}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}}|j                  }|j                  } |       }|sd	d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      t	        j                  |      t	        j                  |      dz  }	t        t	        j                  |	            d x}x}}y )Nr   Tisz%(py0)s is %(py3)ssuccessr   r   rV   zbassert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.memory_file
}.exists
}()
}rM   )rT   rU   r|   r}   )r   r   r   save_sessionrY   rZ   r[   r\   r]   r^   r_   r`   rH   exists)
rb   rM   r   rq   rc   r   rf   re   r   r   s
             r#   test_save_creates_filez.TestBB3_SessionSaveLoad.test_save_creates_file   s    EJJw'($$&w$w$ww$  ) '')'))))))))u)))u))) )))'))))))))))r%   c           	      <   t        j                  |j                  d             t        j                  |j                  d             |j                          ddlm} t        d      5   |dddt        |j                        d	
      }d d d        j                         }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t!        t        j"                  |            d x}}|j$                  }d}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }dd|iz  }t!        t        j"                  |            d x}x}
}	y # 1 sw Y   xY w)Nr   worldr   r;   r/   rA   rB    rC   rD   Tr   r   loadedr   r   rV   r   rQ   rw   agent2rS   rW   rX   )r   r   r   r   rJ   r<   r   rK   rH   load_sessionrY   rZ   r[   r\   r]   r^   r_   r`   rx   )rb   rM   r<   r   r   rq   rc   r   rf   rd   re   rg   s               r#   test_load_restores_turn_countz5TestBB3_SessionSaveLoad.test_load_restores_turn_count   sZ   EJJw'(EJJw'( 	B() 	 !.  1 12"F	 $$&v~vvv  %A% A%%%% A%%%%%%v%%%v%%% %%%A%%%%%%%	 	s   *!HHc           	         t        j                  |j                  d             |j                          ddlm} t        d      5   |dddt        |j                        d	      }d d d        j                          |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}}y # 1 sw Y   NxY w)Nz
restore mer   r;   r/   rA   rB   r   rC   rD   r   rQ   r   r   r   r   r   r   )r   r   r   r   rJ   r<   r   rK   rH   r   rt   r   rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   rM   r<   r   rq   rd   r   r   r   r   s
             r#   test_load_restores_historyz2TestBB3_SessionSaveLoad.test_load_restores_history   s   EJJ|,-A() 	 !.  1 12"F	 	>>'s>"'a'"a''''"a''''''s'''s''''''6'''6'''>'''"'''a'''''''	 	s   !F33F=c           
         ddl m} t        d      5   |dddt        |dz        d	      }d d d        j	                         }d
}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}}y # 1 sw Y   xY w)Nr   r;   r/   ghostrB   r   znonexistent.jsonlrC   rD   Fr   r   r   r   r   rV   )rJ   r<   r   rK   r   rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   rM   r    r<   r   r   rq   rc   r   rf   s
             r#   ,test_load_returns_false_for_nonexistent_filezDTestBB3_SessionSaveLoad.test_load_returns_false_for_nonexistent_file   s    A() 	 . +> >?"F	 $$&vvvv	 	s   C**C3c           	         t        j                  |j                  d             |j                          ddlm} t        d      5   |dddt        |j                        d	      }d d d        j                          |j                  }d}||kD  }|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 # 1 sw Y   xY w)Nzcount tokensr   r;   r/   rA   rB   r   rC   rD   r   )z:%(py2)s
{%(py2)s = %(py0)s.total_prompt_tokens
} > %(py5)sr   rS   rW   rX   )r   r   r   r   rJ   r<   r   rK   rH   r   total_prompt_tokensrY   rZ   r[   r\   r]   r^   r_   r`   )	rb   rM   r<   r   rc   rd   re   rf   rg   s	            r#   %test_save_load_preserves_token_countsz=TestBB3_SessionSaveLoad.test_save_load_preserves_token_counts   s    EJJ~./A() 	 !.  1 12"F	 	))-A-)A----)A------v---v---)---A-------	 	s   !EEN)	r   r   r   r   r   r   r   r   r   r   r%   r#   r   r      s    ,*&&( .r%   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)TestBB4_CTMExtractionz'BB4: CTM extraction from response text.c                 D   ddl m} d} ||      }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }	t        t        j                  |	            d x}x}}|d   }
d}|
|k(  }|slt        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}
x}}y )Nr   extract_ctm_blocksz0Some text [CTM]Important insight[/CTM] more textr   rQ   r   r   blocksr   r   r   zImportant insightz%(py1)s == %(py4)srn   r|   assert %(py6)sr}   core.gemini_command_centres.ctmr   r   rY   rZ   r[   r\   r]   r^   r_   r`   rb   r$   r   r(   r   rq   r   rd   r   r   rp   re   r   s                r#   test_ctm_block_extractedz.TestBB4_CTMExtraction.test_ctm_block_extracted   s    FA#D)6{a{a{ass66{aay///y/////y////y///////////r%   c                 D   ddl m} d} ||      }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }	t        t        j                  |	            d x}x}}|d   }
d}|
|k(  }|slt        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}
x}}|d   }
d}|
|k(  }|slt        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}
x}}y )Nr   r   z)[CTM]First[/CTM] middle [CTM]Second[/CTM]r   rQ   r   r   r   r   r   r   Firstr   r   r   r}   r   Secondr   r   s                r#   test_multiple_ctm_blocksz.TestBB4_CTMExtraction.test_multiple_ctm_blocks   s<   F:#D)6{a{a{ass66{aay#G#yG####yG###y###G#######ay$H$yH$$$$yH$$$y$$$H$$$$$$$r%   c                 B   ddl m} d} ||      }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }	t        t        j                  |	            d x}x}}d}
|d   }|
|v }|slt        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}
x}}y )Nr   r   z[CTM]
Line one
Line two
[/CTM]r   rQ   r   r   r   r   r   r   zLine onerl   )z%(py1)s in %(py4)sr   r   r}   r   r   s                r#   test_multiline_ctm_blockz.TestBB4_CTMExtraction.test_multiline_ctm_block  s    F2#D)6{a{a{ass66{a&VAY&zY&&&&zY&&&z&&&Y&&&&&&&r%   c                 p   ddl m} d} ||      }g }||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd	|iz  }t        t        j                  |            d x}}y )
Nr   r   zNo CTM blocks hererQ   r   r   r   r   rV   )
r   r   rY   rZ   r[   r\   r]   r^   r_   r`   )	rb   r$   r   r(   r   rq   rc   r   rf   s	            r#    test_no_ctm_blocks_returns_emptyz6TestBB4_CTMExtraction.test_no_ctm_blocks_returns_empty
  sl    F##D)v|vvvr%   c                 ^   |\  }}d|_         t        d|d         5  t        d|d         5  t        j                  |j	                  d             ddd       ddd       |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}	}y# 1 sw Y   FxY w# 1 sw Y   KxY w)z@When model response contains [CTM] tag, ctm_buffer is populated.z0Analysis done. [CTM]Key insight discovered[/CTM]r=   r   r>   r   zanalyse thisNr   >=)zP%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.ctm_buffer
})
} >= %(py8)sr   rM   r   r   r   )r(   r   r   r   r   r   r   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   rM   r$   r9   r7   r6   rq   rd   r   r   r   r   s               r#   test_auto_ctm_in_chat_responsez4TestBB4_CTMExtraction.test_auto_ctm_in_chat_response  s   %6"]ODlS`Fab 	8FU`Hab 8EJJ~678	8 ##)s#$))$))))$))))))s)))s))))))5)))5)))#)))$))))))))))8 8	8 	8s"   F"%FF"F	F""F,N)	r   r   r   r   r   r   r   r   r   r   r%   r#   r   r      s    10%'	*r%   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestBB5_DaemonTaskPopz BB5: Daemon task pop from queue.c           	      *   ddl m} |d   dz  }ddd}t        |d      5 }|j                  t	        j
                  |      d	z          d d d        t        d
|d         5  t        d|d         5  t        d|d         5   ||t        |            }|j                         }d d d        d d d        d d d        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}
}	|d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d x}x}	}|d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d x}x}	}y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   GeminiDaemonr   test_agent.jsonlztask-001zdo workidpromptw
5core.gemini_command_centres.daemon.GCC_HEARTBEATS_DIRr   2core.gemini_command_centres.daemon.GCC_RESULTS_DIRr   6core.gemini_command_centres.daemon.GCC_TASK_QUEUES_DIRrM   task_queue_file)is not)z%(py0)s is not %(py3)spoppedr   r   rV   r   rQ   r   r   r   r}   r   "core.gemini_command_centres.daemonr   openwritejsondumpsr   rK   	_pop_taskrY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rM   r   
queue_filetaskfdaemonr  rq   rc   r   rf   rp   re   r   r   s                    r#    test_pop_returns_task_from_queuez6TestBB5_DaemonTaskPop.test_pop_returns_task_from_queue  s   C!(+.@@
 I6*c" 	-aGGDJJt$t+,	- JLYeLfg 	0K\ZcMde 0SUabjUkl 0)s:WF#--/F00	0 "!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!d|)z)|z))))|z)))|)))z)))))))h,9,9,,,,9,,,,,,9,,,,,,,	- 	-
0 00 0	0 	0sG   (I!J/I;?$I.#I;+J!I+.I83I;;J	 JJc           	      D   ddl m} |d   dz  }ddd}t        |d      5 }|j                  t	        j
                  |      d	z          d d d        t        d
|d         5  t        d|d         5  t        d|d         5   ||t        |            }|j                          |j                         }d d d        d d d        d d d        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}
}	y # 1 sw Y   +xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   r   ztask-002z	remove mer   r   r   r   r   r   r   r  r  r   r   popped_againr   r   rV   r  )rb   r$   rM   r   r  r  r  r  r  rq   rc   r   rf   s                r#   test_pop_removes_task_from_filez5TestBB5_DaemonTaskPop.test_pop_removes_task_from_file1  sT   C!(+.@@
 K8*c" 	-aGGDJJt$t+,	- JLYeLfg 	6K\ZcMde 6SUabjUkl 6)s:WF$$&#)#3#3#5L	66	6  $#|t####|t######|###|###t#######	- 	-
6 66 6	6 	6sG   (E1F/F
?4E>3F
;F1E;>FF

F	FFc           	         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                         }d d d        d d d        d d d        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}}y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   zempty.jsonlr   r   r   r   r  r  r   r   r   r   r   rV   )r  r   touchr   rK   r  rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rM   r   r  r  r   rq   rc   r   rf   s              r#   !test_pop_empty_queue_returns_nonez7TestBB5_DaemonTaskPop.test_pop_empty_queue_returns_noneC  s   C!(+m;
JLYeLfg 	0K\ZcMde 0SUabjUkl 0)s:WF#--/F00	0 v~vvv	0 00 0	0 	0s:   ED<$D02D<:E0D95D<<E	EEc           	         ddl m} |d   dz  }ddddd	dd
ddg}t        |d      5 }|D ])  }|j                  t	        j
                  |      dz          + 	 d d d        t        d|d         5  t        d|d         5  t        d|d         5   ||t        |            }|j                          |j                         j                         j                         }	|	D 
cg c](  }
|
j                         st	        j                  |
      * }}
d d d        d d d        d d d        t              }d}||k(  }|st        j                  d|fd||f      dt!        j"                         v st        j$                  t              rt        j&                  t              nddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      t        j&                  |      dz  }dd|iz  }t)        t        j*                  |            d x}x}}|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j&                  |      t        j&                  |      dz  }dd |iz  }t)        t        j*                  |            d x}x}}y # 1 sw Y   hxY wc c}
w # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)!Nr   r   r   zmulti.jsonlt1firstr   t2secondt3thirdr   r   r   r   r   r   r  r  r   rQ   r   r   	remainingr   r   r   r   r   r   r   r}   )r  r   r  r	  r
  r  r   rK   r  	read_textstrip
splitlinesloadsr   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rM   r   r  tasksr  tr  r*   lr  rq   r   rd   r   r   rp   re   r   s                       r#   test_pop_leaves_remaining_tasksz5TestBB5_DaemonTaskPop.test_pop_leaves_remaining_tasksQ  sG   C!(+m;
7+8,7+

 *c" 	.a .

1,-.	. JLYeLfg 	NK\ZcMde NSUabjUkl N)s:WF$$&(224::<GGIG8? M11779A MI MNN	N 9~""~""""~""""""s"""s""""""9"""9"""~""""""""""|D!)T)!T))))!T)))!)))T)))))))	. 	. !NN NN N	N 	Ns`   /J?0K+ KAK$K
:K
KKK+?K	KKKK(	#K++K5N)r   r   r   r   r  r  r  r'  r   r%   r#   r   r     s    *-$$$*r%   r   c                   "    e Zd ZdZd Zd Zd Zy)TestBB6_DaemonHeartbeatz$BB6: Daemon heartbeat file creation.c           	         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                          |d   dz  }d d d        d d d        d d d        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}}y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   r   r   r   r   r   r  r  test_agent.jsonAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}hb_filer   )r  r   r  r   rK   
_heartbeatr   r[   r\   rY   r]   r^   r_   r`   )
rb   r$   rM   r   r  r  r-  rc   re   r   s
             r#   test_heartbeat_file_createdz3TestBB6_DaemonHeartbeat.test_heartbeat_file_createdn  s(   C!(+.@@
JLYeLfg 	MK\ZcMde MSUabjUkl M)s:WF%%'*<8;LLGMM	M ~~~ww~M MM M	M 	Ms:   EE,D9:EE9E>EE	
EEc           	         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                          |d   dz  }t        j                  |j                               }d d d        d d d        d d d        d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}
}	d}||v }
|
st        j                  d|
fd||f      t        j                  |      dt        j                         v st        j                   |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}
|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}
}	y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   r   r   r   r   r   r  r  r+  rM   rA   rQ   r   r   r   r}   	timestamprl   z%(py1)s in %(py3)sdatarn   ro   r   rV   statusrunning)r  r   r  r   rK   r.  r
  r#  r   rY   rZ   r^   r_   r`   r[   r\   r]   )rb   r$   rM   r   r  r  r-  r3  rp   re   rq   r   r   r   rf   s                  r#   "test_heartbeat_contains_agent_namez:TestBB6_DaemonHeartbeat.test_heartbeat_contains_agent_name}  s   C!(+.@@
JLYeLfg 	;K\ZcMde ;SUabjUkl ;)s:WF%%'*<8;LLG::g&7&7&9:D	;;	; G},,},,,,},,,},,,,,,,,,,"{d""""{d"""{""""""d"""d"""""""H~**~****~***~**********; ;; ;	; 	;s;   I5I(AII(%I5I% I((I2	-I55I?c           	         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                  d       |d   dz  }t        j                  |j                               }d d d        d d d        d d d        d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}
}	y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   r   r   r   r   r   r  r  stoppedr5  r+  r5  rQ   r   r   r   r}   )r  r   r  r   rK   r.  r
  r#  r   rY   rZ   r^   r_   r`   )rb   r$   rM   r   r  r  r-  r3  rp   re   rq   r   r   s                r#   test_heartbeat_status_stoppedz5TestBB6_DaemonHeartbeat.test_heartbeat_status_stopped  s,   C!(+.@@
JLYeLfg 	;K\ZcMde ;SUabjUkl ;)s:WF%%Y%7*<8;LLG::g&7&7&9:D	;;	; H~**~****~***~**********; ;; ;	; 	;s;   EEAD8E'E8E=EE		EEN)r   r   r   r   r/  r7  r;  r   r%   r#   r)  r)  k  s    . +$+r%   r)  c                       e Zd ZdZd Zd Zy)TestBB7_DaemonResultFilez!BB7: Daemon result file creation.c           
         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                  dddddd       |d   dz  }d d d        d d d        d d d        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}}t        j                  |j!                               }
|
d   }d}||k(  }|slt        j"                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }t        t        j                  |            d x}x}}|
d   }d}||k(  }|slt        j"                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }t        t        j                  |            d x}x}}|
d   }d}||u }|slt        j"                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }t        t        j                  |            d x}x}}y # 1 sw Y   cxY w# 1 sw Y   hxY w# 1 sw Y   mxY w)Nr   r   r   r   r   r   r   r   r  r  ztask-999zgreat resulttestr   T)r   ztask-999.jsonr,  result_filer   task_idrQ   r   r   r   r}   r   r   r   z%(py1)s is %(py4)s)r  r   r  r   rK   _write_resultr   r[   r\   rY   r]   r^   r_   r`   r
  r#  r   rZ   )rb   r$   rM   r   r  r  r@  rc   re   r   r3  rp   rq   r   s                 r#   test_result_file_createdz1TestBB7_DaemonResultFile.test_result_file_created  sF   C!(+.@@
JLYeLfg 
	LK\ZcMde 	LSUabjUkl L)s:WF(("&)V< $	 )  #/y"9O"KKL	L
	L !!#!########{###{###!##########zz+//12I,*,*,,,,*,,,,,,*,,,,,,,H~//~////~///~//////////I&$&$&&&&$&&&&&&$&&&&&&&L L	L 	L
	L 
	Ls:   K=K04K#K0
K=#K-(K00K:	5K==Lc           
         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }|j                  ddddddd       |d   dz  }d d d        d d d        d d d        t        j                  j                               }|d   }d}	||	u }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}
}	|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}
}	y # 1 sw Y   =xY w# 1 sw Y   BxY w# 1 sw Y   GxY w)Nr   r   r   r   r   r   r   r   r  r  z	task-failz	API Errorbrokenr   F)r   errorztask-fail.jsonr   r   rB  r   r   r}   rG  rQ   r   )r  r   r  r   rK   rC  r
  r#  r   rY   rZ   r^   r_   r`   )rb   r$   rM   r   r  r  r@  r3  rp   re   rq   r   r   s                r#   test_result_file_failurez1TestBB7_DaemonResultFile.test_result_file_failure  s   C!(+.@@
JLYeLfg 	MK\ZcMde 
MSUabjUkl 	M)s:WF((##*h? %) )  #/y"9<L"LK	M
M	M zz+//12I'%'%''''%''''''%'''''''G}++}++++}+++}++++++++++	M 	M
M 
M	M 	Ms:   GG5F>GG>GGG	GG"N)r   r   r   r   rD  rH  r   r%   r#   r=  r=    s    +'0,r%   r=  c                   "    e Zd ZdZd Zd Zd Zy)TestBB8_LauncherTmuxz6BB8: Launcher creates tmux sessions (mock subprocess).c                 N   ddl m} t        d      5 }t        d      5  t        d      |_         |d       d d d        d d d        j
                  D cg c]  }|j                  d   d   dk(  r| }}t        |      }d	}||k\  }|st        j                  d
|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y # 1 sw Y   QxY w# 1 sw Y   VxY wc c}w )Nr   )
launch_allsubprocess.run
time.sleep
returncodeFverbosetmux   r   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sr   
tmux_callsr   r   r   )$core.gemini_command_centres.launcherrL  r   r	   r1   call_args_listargsr   rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   rL  mock_runcallrU  rq   r   rd   r   r   s
             r#   test_launch_all_calls_tmuxz/TestBB8_LauncherTmux.test_launch_all_calls_tmux  s"   C#$ 	*|$ *(1Q(?%5)*	* &44
yy|A&( 

 
 :#!#!####!######s###s######:###:######!#######* *	* 	*
s'   FFFF"F	FFc                    ddl m} t        d      5 }t        d      5  t        d      |_         |dd      }d d d        d d d        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}}y # 1 sw Y   xY w# 1 sw Y   xY w)Nr   
launch_onerM  rN  rO  orchestratorFrQ  Tr   r   r   r   r   rV   )rV  r^  r   r	   r1   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r^  rY  r   rq   rc   r   rf   s           r#   test_launch_one_successz,TestBB8_LauncherTmux.test_launch_one_success  s    C#$ 	C|$ C(1Q(?%#NEBC	C
 v~vvv	C C	C 	Cs!   C<C0C<0C9	5C<<Dc                 n   ddl m}  |dd      }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}}y )Nr   r]  nonexistent_centreFrQ  r   r   r   r   r   rV   )
rV  r^  rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r^  r   rq   rc   r   rf   s          r#   test_launch_one_unknown_namez1TestBB8_LauncherTmux.test_launch_one_unknown_name  sj    C0%@vvvvr%   N)r   r   r   r   r[  r`  rc  r   r%   r#   rJ  rJ    s    @$r%   rJ  c                   "    e Zd ZdZd Zd Zd Zy)TestBB9_WatchdogStaleDetectionz&BB9: Watchdog detects stale heartbeat.c                    ddl m} |d   dz  }t        j                  t        j
                        t        d      z
  j                         }|j                  t        j                  |dd             t        d	|d         5   |d
      }|j                  |      }d d d        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}}y # 1 sw Y   xY w)Nr   GCCWatchdogr   orchestrator.jsoni,  )secondsr6  r1  r5  7core.gemini_command_centres.watchdog.GCC_HEARTBEATS_DIRx   stale_thresholdTr   r   is_staler   r   rV   )$core.gemini_command_centres.watchdogrh  r   nowr   utcr   	isoformat
write_textr
  r  r   	_is_stalerY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rh  r-  old_tswatchdogrp  rq   rc   r   rf   s              r#   test_stale_file_detectedz7TestBB9_WatchdogStaleDetection.test_stale_file_detected  s    D|,/BBLL&3)??
)+ 	 	4::Fi&PQRLl[gNhi 	3"37H))'2H	3  x4x4xx4		3 	3s   EEc                    ddl m} |d   dz  }t        j                  t        j
                        j                         }|j                  t        j                  |dd             t        d|d         5   |d	      }|j                  |      }d d d        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}}y # 1 sw Y   xY w)Nr   rg  r   ri  r6  rk  rl  rm  rn  Fr   r   rp  r   r   rV   )rq  rh  r   rr  r   rs  rt  ru  r
  r  r   rv  rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rh  r-  fresh_tsrx  rp  rq   rc   r   rf   s              r#   test_fresh_file_not_stalez8TestBB9_WatchdogStaleDetection.test_fresh_file_not_stale  s    D|,/BB<<-7794::H	&RSTLl[gNhi 	3"37H))'2H	3 ! x5    x5      x   x   5       		3 	3s   6D??Ec                    ddl m} |d   dz  } |d      }|j                  |      }d}||u }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}}y )Nr   rg  r   zno_such_file.jsonrm  rn  Tr   r   rp  r   r   rV   )rq  rh  rv  rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   r$   rh  missing_filerx  rp  rq   rc   r   rf   s
             r#   test_missing_file_is_stalez9TestBB9_WatchdogStaleDetection.test_missing_file_is_stale  s    D#L14GGs3%%l3x4x4xx4r%   N)r   r   r   r   ry  r|  r  r   r%   r#   re  re    s    0 ! r%   re  c                   "    e Zd ZdZd Zd Zd Zy)TestBB10_WatchdogRespawnz'BB10: Watchdog respawns crashed centre.c                    ddl m}m}  |       }t        j                  |d      5 }t        j                  |dd      5  t        d|d         5  |D ]!  }|d   |d	    d
z  }|j                  d       # |d d D ]3  }|d   |d	    d
z  }	|j                  |	      s#|j                  |       5 	 d d d        d d d        d d d        j                          y # 1 sw Y   *xY w# 1 sw Y   .xY w# 1 sw Y   2xY w)Nr   rh  CENTRES_CONFIG_respawnrv  Tr0   rl  r   rE   z.jsonz{}r   )	rq  rh  r  r   objectru  rv  _maybe_respawnassert_called_once)
rb   r$   rh  r  rx  mock_respawnchbcentrer-  s
             r#   'test_respawn_called_for_stale_heartbeatz@TestBB10_WatchdogRespawn.test_respawn_called_for_stale_heartbeat#  s   T=\\(J/ 	<<h$G <TVbcoVpq 
<+ ,),7QvYKu:MMd+,
 #1!"4 <".|"<&.AQQV?W"W#--g6$33F;<
<<	< 	'')
< 
<< <	< 	<sA   C3C'ACC2C':C3C$ C''C0	,C33C<c                    ddl m}m}  |       }|d   }t        j                         |j
                  |d   <   t        j                  |d      5 }|j                  |       d d d        j                          y # 1 sw Y   xY w)Nr   r  rE   r  )
rq  rh  r  time	monotonic_last_respawnr   r  r  assert_not_called)rb   r$   rh  r  rx  r  r  s          r#    test_respawn_skipped_in_cooldownz9TestBB10_WatchdogRespawn.test_respawn_skipped_in_cooldown8  st    T=" 261Avf~.\\(J/ 	,<##F+	, 	&&(	, 	,s   A::Bc                    ddl m}m}m}  |       }|d   }||j                  |d   <   d |j
                  |d   <   t        j                  |d      5 }|j                  |       d d d        j                          y # 1 sw Y   xY w)Nr   )rh  MAX_RESPAWN_ATTEMPTSr  rE   r  )
rq  rh  r  r  _respawn_countsr  r   r  r  r  )rb   r$   rh  r  r  rx  r  r  s           r#   )test_respawn_not_called_when_max_exceededzBTestBB10_WatchdogRespawn.test_respawn_not_called_when_max_exceededF  s    jj="3G  015vf~.\\(J/ 	,<##F+	, 	&&(	, 	,s   A<<BN)r   r   r   r   r  r  r  r   r%   r#   r  r     s    1**))r%   r  c                   "    e Zd ZdZd Zd Zd Zy)TestWB1_TokenCountingz1WB1: Token counting from response usage_metadata.c                 l   t        j                  |j                  d             |j                  }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}|j                  }d	}||k(  }|st	        j
                  d|fd
||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}}y )Nzcount these tokensr+   rQ   z;%(py2)s
{%(py2)s = %(py0)s.total_prompt_tokens
} == %(py5)srM   rS   rW   rX   r,   z?%(py2)s
{%(py2)s = %(py0)s.total_completion_tokens
} == %(py5)sr   r   r   r   rY   rZ   r[   r\   r]   r^   r_   r`   total_completion_tokensrb   rM   r9   rc   rd   re   rf   rg   s           r#   $test_token_counts_updated_after_chatz:TestWB1_TokenCounting.test_token_counts_updated_after_chat\  s    EJJ345((/C/(C////(C//////u///u///(///C///////,,22,2222,222222u222u222,2222222222r%   c                    t        j                  |j                  d             t        j                  |j                  d             |j                  }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd	|iz  }t        t	        j                  |            d x}x}}|j                  }d
}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd	|iz  }t        t	        j                  |            d x}x}}y )Nz
first callzsecond call   rQ   r  rM   rS   rW   rX   r+   r  r  r  s           r#   test_token_counts_accumulatez2TestWB1_TokenCounting.test_token_counts_accumulatea  s   EJJ|,-EJJ}-.((/C/(C////(C//////u///u///(///C///////,,33,3333,333333u333u333,3333333333r%   c                 H   |j                         }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d	}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d
}|d	   }||k  }d}||k  }	|r|	st        j                  d||	fd|||f      t        j                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}x}	x}}y )NrM   rl   r2  usager4  r   rV   r   utilisation_pctg        g      Y@)<=r  )z%(py1)s <= %(py5)sz%(py5)s <= %(py7)s)rn   rV   rX   assert %(py9)spy9)	get_context_usagerY   rZ   r^   r[   r\   r]   r_   r`   )rb   rM   r  rp   rq   r   rf   rd   r   re   rg   @py_format10s               r#   test_context_usage_returns_dictz5TestWB1_TokenCounting.test_context_usage_returns_dicth  s   '')w%w%w%%$-$----$---$---------------- ) E)))) E))) ))))))E)))E)))))))7e-.7s.77%7.%77777s.%777s777.777%77777777r%   N)r   r   r   r   r  r  r  r   r%   r#   r  r  Y  s    ;3
48r%   r  c                   "    e Zd ZdZd Zd Zd Zy)TestWB2_HistoryCompactionz7WB2: History compaction when approaching context limit.c                    ddl m} t        d      D ]J  }|j                  j	                  ddd| igd       |j                  j	                  ddd	| igd       L |j                          |d
z  d
z   }|j                  }t        |      }||k  }|s7t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }	t        t        j                  |	            d x}x}}y )Nr   )COMPACTION_KEEP_TURNSr+   r   r(   msg r   r)   rF   resp r   )r  )zM%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.history
})
} <= %(py7)sr   rM   expected_maxrT   rn   ro   rV   rX   r  r  )rJ   r  rangert   append_compact_historyr   rY   rZ   r[   r\   r]   r^   r_   r`   )
rb   rM   r  ir  rq   rd   r   rg   r  s
             r#   test_compaction_reduces_historyz9TestWB2_HistoryCompaction.test_compaction_reduces_historys  s8   K s 	VAMM  &VtA3Z<P;Q!RSMM  'faSk=R<S!TU	V 	  .1Q6==1s=!1!\1111!\111111s111s11111151115111=111!111111\111\1111111r%   c                 N   t        d      D ]J  }|j                  j                  ddd| igd       |j                  j                  ddd| igd       L |j                          |j                  d   d	   d   d   }d
}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd|iz  }t        t	        j                  |            d x}}y )N<   r   r(   r  r  rF   r  r   r)   zCONTEXT COMPACTEDrl   r2  	first_msgr4  r   rV   )r  rt   r  r  rY   rZ   r^   r[   r\   r]   r_   r`   )rb   rM   r  r  rp   rq   r   rf   s           r#   &test_compaction_inserts_summary_markerz@TestWB2_HistoryCompaction.test_compaction_inserts_summary_marker  s    r 	VAMM  &VtA3Z<P;Q!RSMM  'faSk=R<S!TU	V 	  MM!$W-a08	"/"i////"i///"//////i///i///////r%   c                 0   dddigddddigdg|_         t        |j                         }|j                          |j                   }t        |      }||k(  }|s7t        j                  d|fd||f      d	t        j                         v st        j                  t              rt        j                  t              nd	d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}x}}y )Nr   r(   r   r  rF   hirQ   )zM%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.history
})
} == %(py7)sr   rM   original_lenr  r  r  )rt   r   r  rY   rZ   r[   r\   r]   r^   r_   r`   )rb   rM   r  rq   rd   r   rg   r  s           r#   /test_compaction_not_triggered_for_small_historyzITestWB2_HistoryCompaction.test_compaction_not_triggered_for_small_history  s    '8&9:'78
 5==) ==1s=!1!\1111!\111111s111s11111151115111=111!111111\111\1111111r%   N)r   r   r   r   r  r  r  r   r%   r#   r  r  p  s    A2	02r%   r  c                       e Zd ZdZd Zd Zy)TestWB3_ErrorRetryLogicz!WB3: Error retry logic in daemon.c           	      F   ddl m} |d   dz  }|j                          dfd}t        d|d         5  t        d|d	         5  t        d
|d         5   ||t	        |            }t        j
                  |d|      5  ddd}t        j                  |j                  |             d d d        d d d        d d d        d d d        d}	|	k(  }
|
st        j                  d|
fd|	f      dt        j                         v st        j                        rt        j                        ndt        j                  |	      dz  }dd|iz  }t        t        j                   |            d x}
}	y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)Nr   r   r   r   c                 8   K   dz  dk  rt        d      yw)Nr      zSimulated API failurezsuccess after retries)ConnectionError)msg
call_counts    r#   failing_chatzNTestWB3_ErrorRetryLogic.test_retry_increments_on_failure.<locals>.failing_chat  s&     !OJA~%&=>>*s   r   r   r   r   r  r  r   )side_effectz
retry-taskzdo retry testr   r  rQ   r   r  r   r   rV   )r  r   r  r   rK   r  r   r   _process_taskrY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   rM   r9   r   r  r  r  r  rq   rc   r   rf   r  s                @r#    test_retry_increments_on_failurez8TestWB3_ErrorRetryLogic.test_retry_increments_on_failure  sa   C!(+.@@

	+ JLYeLfg 	@K\ZcMde @SUabjUkl @)s:WFeVN @&2oNF$8$8$>?@@@	@ zQzQzzQ@ @@ @@ @	@ 	@sS   FF,E?*E3	,E?4F<F3E<8E??FFF	FF c           	         ddl m} |d   dz  }|j                          t        d|d         5  t        d|d         5  t        d	|d         5   ||t	        |      
      }ddd}|j                  |t        d             |d   dz  }d d d        d d d        d d d        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}}	t        j                   |j#                               }|d   }d}	||	u }|slt        j$                  d|fd||	f      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	j&                  }d}||k(  }	|	st        j$                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd |iz  }t        t        j                  |            d x}x}	}y # 1 sw Y   +xY w# 1 sw Y   0xY w# 1 sw Y   5xY w)!Nr   r   r   r   r   r   r   r   r  r  z	fail-taskzthis will failr   zcritical failurezfail-task.jsonr,  r@  r   r   Fr   rB  r   r   r}   r   rQ   )z4%(py2)s
{%(py2)s = %(py0)s.tasks_failed
} == %(py5)sr  rS   rW   rX   )r  r   r  r   rK   _handle_error
ValueErrorr   r[   r\   rY   r]   r^   r_   r`   r
  r#  r   rZ   tasks_failed)rb   r$   rM   r   r  r  r  r@  rc   re   r   r3  rp   rq   r   rd   rf   rg   s                     r#   &test_handle_error_writes_failed_resultz>TestWB3_ErrorRetryLogic.test_handle_error_writes_failed_result  s   C!(+.@@
JLYeLfg 	MK\ZcMde MSUabjUkl M)s:WF"-9IJD((z:L/MN".y"9<L"LKMM	M !!#!########{###{###!##########zz+//12I'%'%''''%''''''%'''''''""'a'"a''''"a''''''v'''v'''"'''a'''''''M MM M	M 	Ms:   KK <J3
K K3J=8K  K
	KKN)r   r   r   r   r  r  r   r%   r#   r  r    s    +6(r%   r  c                       e Zd ZdZd Zy)TestWB4_TaskQueueFileLockingu7   WB4: Task queue file locking — concurrent pop safety.c           	      .   ddl m} |d   dz  }ddddd	dg}t        |d
      5 }|D ])  }|j                  t	        j
                  |      dz          + 	 ddd       t        d|d         5  t        d|d         5  t        d|d         5   ||t        |            }|j                         }	|j                         }
ddd       ddd       ddd       	d   }
d   }||k7  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|	d   |
d   h}ddh}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   xY w# 1 sw Y   2xY w# 1 sw Y   7xY w# 1 sw Y   <xY w)z>Two sequential pops from a 2-task queue return distinct tasks.r   r   r   zconcurrent.jsonlzc-1ztask oner   zc-2ztask twor   r   Nr   r   r   r   r  r  r   !=z%(py1)s != %(py4)sr   r   r}   rQ   r   )r  r   r  r	  r
  r  r   rK   r  rY   rZ   r^   r_   r`   )rb   r$   rM   r   r  r$  r  r%  r  r  r  rp   re   rq   r   r   s                   r#   !test_concurrent_pops_unique_tasksz>TestWB4_TaskQueueFileLocking.test_concurrent_pops_unique_tasks  s   C!(+.@@
J/J/
 *c" 	.a .

1,-.	. JLYeLfg 	0K\ZcMde 0SUabjUkl 0)s:WF",,.E#--/F00	0 T{*fTl*{l****{l***{***l*******dVD\*<uen<*n<<<<*n<<<*<<<n<<<<<<<	. 	.0 00 0	0 	0sG   /G#,H
<G=4G0 G=H
#G-0G:5G==H	H

HN)r   r   r   r   r  r   r%   r#   r  r    s
    A=r%   r  c                   (    e Zd ZdZd Zd Zd Zd Zy)TestWB5_CTMJsonlFormatz!WB5: CTM JSONL format validation.c                    ddl m} dt        |        }t        d|d         5  t        d|d         5   ||dd	
      }d d d        d d d        d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}t        |d         }
|
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}}|
j                         j                         j!                         }t#        |      }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t"              rt	        j                  t"              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }	dd|	iz  }t        t	        j                  |            d x}x}}t%        j&                  |d         }d}||v }|st	        j
                  d|fd||f      t	        j                  |      d t        j                         v st	        j                  |      rt	        j                  |      nd d!z  }d"d#|iz  }t        t	        j                  |            d x}}|d$   }d%| }||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}|d&   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}|d'   }d	}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}d(}||v }|st	        j
                  d|fd||f      t	        j                  |      d t        j                         v st	        j                  |      rt	        j                  |      nd d!z  }d"d#|iz  }t        t	        j                  |            d x}}y # 1 sw Y   hxY w# 1 sw Y   mxY w))Nr   	ctm_to_kgwb5_unique_r=   r   r>   r   zTest contententitycategoryr5  okrQ   r   r   r   r}   filer,  written_filer   r   r   r   linesr   r   r   r   rl   r2  entryr4  r   rV   sourcezgcc-r*   typer1  )r   r  r   r   rY   rZ   r^   r_   r`   r   r   r[   r\   r]   r   r!  r"  r   r
  r#  )rb   r$   r  unique_namer   rp   re   rq   r   r   r  rc   r  r   rd   r   r  r   rf   s                      r#   !test_ctm_to_kg_writes_valid_jsonlz8TestWB5_CTMJsonlFormat.test_ctm_to_kg_writes_valid_jsonl  s   = $BtH:.DlS`Fab 	SFU`Hab S";RS	S h'4'4''''4''''''4'''''''F6N+""$"$$$$$$$$|$$$|$$$"$$$$$$$$$$ &&(..0;;=5zQzQzQss55zQ

58$tu}tutuuX6D"66"66666"6666666"66666666Y1>1>1111>111111>1111111V}((}((((}(((}((((((((((#{e####{e###{######e###e#######S S	S 	Ss"   V3V& V3&V0	+V33V=c                    ddl m} dd l}d|j                         j                  d d  }t        d|d         5  t        d|d         5   ||d	d
        ||dd
      }d d d        d d d        t        d         }|j                         j                         j                         }t        |      }d}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  t              rt        j                   t              nddt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |	      dz  }dd|iz  }t#        t        j$                  |            d x}x}
}	y # 1 sw Y   ]xY w# 1 sw Y   bxY w)Nr   r  agent_append_   r=   r   r>   r   z	Entry oner  r  z	Entry twor  r   rQ   r   r   r  r   r   r   )r   r  uuiduuid4hexr   r   r   r!  r"  r   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   r  _uuidr  r   r  r  rq   r   rd   r   r   s                r#   'test_ctm_to_kg_appends_multiple_entriesz>TestWB5_CTMJsonlFormat.test_ctm_to_kg_appends_multiple_entries  sS   = &ekkm&7&7&;%<=DlS`Fab 	PFU`Hab P+{XF";hOP	P
 F6N+&&(..0;;=5zQzQzQss55zQP P	P 	Ps#   G	
F<!G	<G	G		Gc                 x   ddl m} |d   dz  }t        d|      5   |dd      }d d d        d	   }d
}||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}|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}
}|j                         }d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d x}}y # 1 sw Y   xY w)Nr   )ctm_to_memoryr   r@   r?   zImportant memory entryscout)
agent_namer5  r  rQ   r   r   r   r}   r,  rH   r   rl   r2  r*   r4  r   rV   z	GCC-SCOUT)r   r  r   rY   rZ   r^   r_   r`   r   r[   r\   r]   r   )rb   r$   r  rH   r   rp   re   rq   r   r   rc   r*   r   rf   s                 r#   "test_ctm_to_memory_appends_to_filez9TestWB5_CTMJsonlFormat.test_ctm_to_memory_appends_to_file  s   A"8,{:@+N 	Q"#;PF	Q h'4'4''''4''''''4'''''''!!#!########{###{###!##########'')'2'72222'7222'222222722272222222%{g%%%%{g%%%{%%%%%%g%%%g%%%%%%%	Q 	Qs   J//J9c                    ddl m} t        d|d         5  t        d|d         5   |dd      } |dd	      }d d d        d d d        d
   }d
   }||k7  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y # 1 sw Y   xY w# 1 sw Y   xY w)Nr   r  r=   r   r>   r   rM   z	content 1z	content 2r   r  r  r   r   r}   )r   r  r   rY   rZ   r^   r_   r`   )
rb   r$   r  r1r2rp   re   rq   r   r   s
             r#   test_ctm_id_is_uniquez,TestWB5_CTMJsonlFormat.test_ctm_id_is_unique  s    =DlS`Fab 	5FU`Hab 5w4w45	5
 $x#2d8#x8####x8###x###8#######	5 5	5 	5s!   CCCC	CC"N)r   r   r   r   r  r  r  r  r   r%   r#   r  r    s    +$0 &$r%   r  c                   (    e Zd ZdZd Zd Zd Zd Zy)!TestIntegration_DispatchAndStatusz,Integration: dispatch + status via launcher.c                    ddl m} t        d|d         5   |ddd      }d d d        |d   d	z  }|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}}t        j                  |j                         j                               }|d   }	|	k(  }
|
st        j                  d|
fd|	|f      t        j                  |	      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}	}
|d   }	d}|	|k(  }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}	x}
}y # 1 sw Y   xY w)Nr   )dispatchz8core.gemini_command_centres.launcher.GCC_TASK_QUEUES_DIRr   z	test taskr_  F)targetrR  zorchestrator.jsonlr,  r  r   r   rQ   )z%(py1)s == %(py3)srA  r4  r   rV   r   r   r   r   r}   )rV  r  r   r   r[   r\   rY   r]   r^   r_   r`   r
  r#  r   r!  rZ   )rb   r$   r  rA  r  rc   re   r   r  rp   rq   r   rf   r   s                 r#   test_dispatch_writes_queue_filezATestIntegration_DispatchAndStatus.test_dispatch_writes_queue_file/  sx   AM|\dOef 	R{>5QG	R "(+.BB
  " """"""""z"""z""" """"""""""

://1779:T{%{g%%%%{g%%%{%%%%%%g%%%g%%%%%%%X-+-+----+------+-------	R 	Rs   H33H=c           	         ddl m} t        d|d         5   |d      }d d d        j                         D ]  \  }}|j                  }d} ||      }d}	||	u }
|
st        j                  d|
fd	||	f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}x}x}
}	 y # 1 sw Y   "xY w)Nr   r:  z7core.gemini_command_centres.launcher.GCC_HEARTBEATS_DIRr   FrQ  healthyr   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} is %(py9)sinfo)rT   rU   r|   r}   r  zassert %(py11)spy11)rV  r5  r   itemsgetrY   rZ   r[   r\   r]   r^   r_   r`   )rb   r$   r5  r   rE   r  rc   re   r   @py_assert8r   r  @py_format12s                r#   2test_status_returns_no_heartbeat_for_fresh_installzTTestIntegration_DispatchAndStatus.test_status_returns_no_heartbeat_for_fresh_install;  s    ?Ll[gNhi 	+E*F	+ !,,. 	0JD$88/I/8I&/%/&%////&%//////4///4///8///I///&///%////////	0	+ 	+s   
E  E
c                 0   ddl m} t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            d x}x}}y )Nr   r  rT  rQ   r   r   r  r   r   r   )rV  r  r   rY   rZ   r[   r\   r]   r^   r_   r`   )rb   r  rq   r   rd   r   r   s          r#   $test_centres_config_has_five_entrieszFTestIntegration_DispatchAndStatus.test_centres_config_has_five_entriesE  s    G>"'a'"a''''"a''''''s'''s''''''>'''>'''"'''a'''''''r%   c                 2   ddl m} |D ]  }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d x}}|d   }|j                  }d
} ||      }|stdt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	t        t        j                  |	            d x}x}x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d x}} y )Nr   r  rF   rl   r2  r  r4  r   rV   zgemini-zLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})rn   ro   rV   rX   rE   rG   )rV  r  rY   rZ   r^   r[   r\   r]   r_   r`   
startswith)
rb   r  r  rp   rq   r   rf   rd   r   rg   s
             r#   %test_centres_config_model_ids_presentzGTestIntegration_DispatchAndStatus.test_centres_config_model_ids_presentI  s   G 	(A7a<7a7aaW:3:((33(33333:333(33333333333336Q;6Q6QQ"'?a''''?a'''?''''''a'''a'''''''		(r%   N)r   r   r   r   r  r  r  r  r   r%   r#   r  r  ,  s    6
.0((r%   r  __main__z-mpytestz-vz
--tb=short)cwd)7r   builtinsr[   _pytest.assertion.rewrite	assertionrewriterY   r   r
  r  
subprocessr   r   r   pathlibr   typingr   unittest.mockr   r	   r
   r   r   r  syspathinsertfixturer$   r9   rM   rO   r   r   r   r   r)  r=  rJ  re  r  r  r  r  r  r  r  r   r   
executable__file__r   exitrP  r   r%   r#   <module>r%     s  4      2 2   F F   * +    ) )&  0& &4$ $@G. G.T(* (*VL* L*^2+ 2+j0, 0,f   F'  ' T2) 2)r8 8.#2 #2L0( 0(f= =6A$ A$P#( #(T zZ^^	x4F#F CHHV r%   