
    2                         S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKJ	r
  SSKJ	r	  SSKJr  SSKJ	r  SSKJr  SS	KJr  SS
KJr  SSKrSrSr " S S\5      rS rS rg)zACommon test matrix operations used by Firebase Test Lab commands.    )absolute_import)division)unicode_literalsN)
exceptions)util)log)
properties)
console_iog      @z%H:%M:%Sc                       \ rS rSrSr\R
                  R                  S4S jrS rS r	S r
S rS	 rS
 rS rS rS rSrg)MatrixMonitor'   zA monitor to follow and possibly cancel a single test matrix invocation.

Attributes:
  matrix_id: {str} the unique ID of the matrix being monitored.
  completed_matrix_states: the set of TestMatrix.State enums representing all
    final matrix states.
Nc                 R   Xl         X l        US   U l        US   U l        X@l        [
        R                  " 5       U l        SU l        Ub  XPl	        Or[        R                  R                  R                  R                  5       =(       d    [        U l	        [         R"                  " SS9(       d  U =R                  S-  sl	        U R                  R$                  R&                  nUR(                  SUR*                  S	UR,                  S
UR.                  SUR0                  SUR2                  SUR4                  SUR6                  SUR8                  SUR:                  SUR<                  S0U l        [A        UR.                  UR0                  UR2                  UR4                  UR6                  UR8                  UR:                  /5      U l!        U R                  RD                  R&                  n[A        UR.                  UR0                  UR8                  UR:                  /5      U l#        g)a0  Construct a MatrixMonitor to monitor a single test matrix instance.

Args:
  matrix_id: {str} the unique ID of the matrix being monitored.
  test_type: {str} the type of matrix test being run (e.g. 'robo')
  context: {str:obj} dict containing the gcloud command context, which
    includes the Testing API client & messages libs generated by Apitools.
  clock: injected function which returns a current datetime object when
    called. Used to generate time-stamps on progress messages.
  status_interval_secs: {float} how long to sleep between status checks.
testing_clienttesting_messagesr   NT)error   
ValidatingPendingRunningFinishedErrorUnsupportedzIncompatible EnvironmentzIncompatible Architecture	CancelledInvalidz*Unspecified*)$	matrix_id
_test_type_client	_messages_clockr   
GetProject_project_max_status_length_status_interval_secsr	   VALUEStestmatrix_status_intervalGetInt_DEFAULT_STATUS_INTERVAL_SECSr
   IsInteractiveTestExecutionStateValueValuesEnum
VALIDATINGPENDINGRUNNINGFINISHEDERRORUNSUPPORTED_ENVIRONMENTINCOMPATIBLE_ENVIRONMENTINCOMPATIBLE_ARCHITECTURE	CANCELLEDINVALIDTEST_STATE_UNSPECIFIED_state_namesset_completed_execution_states
TestMatrixcompleted_matrix_states)selfr   	test_typecontextclockstatus_interval_secsexec_statesmatrix_statess           6lib/googlecloudsdk/api_lib/firebase/test/matrix_ops.py__init__MatrixMonitor.__init__0   s   " NO+,DL/0DNKOO%DMD'#7  


 
 
7
7
>
>
@ (
'   %%D1""a'"....CCKYYj7++],,.H--/J{Y**OD (+++,,--, (D$ NN--BBM#&	( $D     c                 *   U R                   R                  R                  n/ n[        5       nUR                   HT  nUR
                  UR                  :X  a&  UR                  [        UR                  5      5        MC  UR                  U5        MV     U(       a;  [        R                  R                  SR                  SR                  U5      S95        [        R                  R                  SR                  U R                   [#        U5      S95        U$ )zReport unsupported device dimensions and return supported test list.

Args:
  matrix: a TestMatrix message.

Returns:
  A list of TestExecution messages which have supported dimensions.
zDSome device dimensions are not compatible and will be skipped:
  {d}z
  dzFirebase Test Lab will execute your {t} test on {n} device(s). More devices may be added later if flaky test attempts are specified.)tn)r   r*   r+   r8   testExecutionsstater1   add_FormatInvalidDimensionenvironmentappendr   statusPrintformatjoinr   len)r<   matrixstatessupported_testsunsupported_dimensionsr%   s         rC   HandleUnsupportedExecutions)MatrixMonitor.HandleUnsupportedExecutionsu   s     ^^))>>FO U%%	v55	5""#:4;K;K#LMt$	 & 	jjFV[[)?@FAC JJ	K	$//S%9	:< rF   c                     U R                  5       nUR                   H  nUR                  U:X  d  M  Us  $    [        R                  " XR
                  5      e)ai  Fetch the TestExecution state of a specific test within a matrix.

This method is only intended to be used for a TestMatrix with exactly one
supported TestExecution. It would be inefficient to use it iteratively on
a larger TestMatrix.

Args:
  test_id: ID of the TestExecution status to find.

Returns:
  The TestExecution message matching the unique test_id.
)GetTestMatrixStatusrL   idr   TestExecutionNotFoundErrorr   )r<   test_idrW   r%   s       rC   _GetTestExecutionStatus%MatrixMonitor._GetTestExecutionStatus   sJ     %%'F%%	G	 & 
/
/
HHrF   c                 *   U R                   R                  R                  nSnSn/ nSn U R                  U5      nU R	                  5       R                  [        5      nUR                  n	U	(       a*  U	R                  =(       d    SnU	R                  =(       d    / nXVS  H?  n
[        R                  R                  SR                  XR                  5       5      5        MA     [        U5      nUR                   UR"                  :X  a  [$        R&                  " U5      eUR                   UR(                  :X  a6  [$        R*                  " SR                  [-        UR.                  5      S95      eUR                   U:w  aG  UR                   n[        R                  R                  SR                  XR0                  U   5      5        UR                   U R2                  ;   a  OU R5                  5         GM  U R7                  5       nUR                   U R8                  ;  a]  [        R:                  " SUR                   5        U R5                  5         U R7                  5       nUR                   U R8                  ;  a  M]  U R=                  UR                   5        g)	ad  Monitor and report the progress of a single running test.

This method prints more detailed test progress messages for the case where
the matrix has exactly one supported test configuration.

Args:
  test_id: str, the unique id of the single supported test in the matrix.

Raises:
  TestLabInfrastructureError if the Test service reports a backend error.

 r   Nz{0} {1}zDevice dimensions are not compatible: {d}. Please use "gcloud firebase test android models list" to determine which device dimensions are compatible.rH   z{0} Test is {1}z+Matrix not yet complete, still in state: %s)r   r*   r+   rb   r   strftime_TIMESTAMP_FORMATtestDetailserrorMessageprogressMessagesr   rR   rS   rT   rstriprV   rM   r0   r   TestLabInfrastructureErrorr1   AllDimensionsIncompatibleErrorrO   rP   r7   r9   _SleepForStatusIntervalr^   r;   debug_LogTestComplete)r<   ra   rX   
last_stater   progresslast_progress_lenrR   	timestampdetailsmsgrW   s               rC   MonitorTestExecutionProgress*MatrixMonitor.MonitorTestExecutionProgress   s    ^^))>>FJEH
++G4f++-(():;i""g	$$*++1r ,-#

)))ZZ\BC .h-		%33E::	77	777@@F)&*<*<= AG A?@ 	@ 
	#\\


*11((46 	7 
99	9
""$C J %%'F
,,d::
:	ii=v||L
""$'')f ,,d::
: 	&,,'
rF   c                     U R                   R                  U R                  U R                  S9n U R                  R
                  R                  U5      $ ! [        R                   a$  n[        R                  " U5      nSUl        UeSnAff = f)zFetch the response from the GetTestMatrix rpc.

Returns:
  A TestMatrix message holding the current state of the created tests.

Raises:
  HttpException if the Test service reports a backend error.
	projectIdtestMatrixIdz=Http error {status_code} while monitoring test run: {message}N)r   %TestingProjectsTestMatricesGetRequestr!   r   r   projects_testMatricesGetapitools_exceptions	HttpErrorcalliope_exceptionsHttpExceptionerror_formatr<   requesteexcs       rC   r^   !MatrixMonitor.GetTestMatrixStatus   s     nnBB--dnn C >G\\//33G<<(( --a0c
I 
i	s   $A B)BBc                 \    U R                  5       n[        R                  " [        5      nUR                   H  nX#R
                  ==   S-  ss'   M     U R                  U5        UR
                  U R                  ;   a  U R                  UR
                  5        gU R                  5         M  )zFMonitor and report the progress of multiple running tests in a matrix.   N)
r^   collectionsdefaultdictintrL   rM   _UpdateMatrixStatusr;   rp   rn   )r<   rW   state_countsr%   s       rC   MonitorTestMatrixProgress'MatrixMonitor.MonitorTestMatrixProgress   s    
'')f ,,S1l''$ZZ A%  ( |,	55	5fll+
""$ rF   c                    / nU R                  5       R                  [        5      n[        R                  " U5       H9  u  pEUS:  d  M  UR                  SR                  U R                  U   US95        M;     UR                  5         SR                  USR                  U5      5      n[        [        U5      U R                  5      U l        [        R                  R                  UR!                  U R                  5      5        g)zUpdate the matrix status line with the current test state counts.

Example: 'Test matrix status: Finished:5 Running:3 Unsupported:2'

Args:
  state_counts: {state:count} a dict mapping a test state to its frequency.
r   z{s}:{c})scz{0} Test matrix status: {1}  N)r   rf   rg   six	iteritemsrQ   rT   r7   sortrU   maxrV   r"   r   rR   writeljust)r<   r   rR   rt   rM   countouts          rC   r   !MatrixMonitor._UpdateMatrixStatus	  s     F&&'89Il3	i&&):):5)AU&KL 4 KKM
*
1
1)SXXf=M
NC "#c(D,C,CDDJJSYYt6678rF   c                     [         R                  " SR                  U5      5        [         R                  R	                  SR                  U R
                  R                  5       5      5        g)z?Let the user know that their test matrix has completed running.z#Test matrix completed in state: {0}z
{0} testing complete.N)r   inforT   rR   rS   r   
capitalize)r<   matrix_states     rC   rp   MatrixMonitor._LogTestComplete  sJ    HH299,GHJJ.55""$& 'rF   c                 D    [         R                  " U R                  5        g )N)timesleepr#   )r<   s    rC   rn   %MatrixMonitor._SleepForStatusInterval$  s    JJt))*rF   c                 "   U R                   R                  U R                  U R                  S9n U R                  R
                  R                  U5        g! [        R                   a$  n[        R                  " U5      nSUl        UeSnAff = f)zjCancels an in-progress TestMatrix.

Raises:
  HttpException if the Test service reports a back-end error.
rz   zCancelTestMatrix: {message}N)r   (TestingProjectsTestMatricesCancelRequestr!   r   r   r~   Cancelr   r   r   r   r   r   s       rC   CancelTestMatrixMatrixMonitor.CancelTestMatrix'  s{     nnEE--dnn F >G
ll((//8(( --a0c6cis   %A B*B		B)r   r   r9   r"   r   r!   r7   r#   r   r;   r   )__name__
__module____qualname____firstlineno____doc__datetimenowrD   r[   rb   rw   r^   r   r   rp   rn   r   __static_attributes__ rF   rC   r   r   '   sQ     &&**$(CJ:I(>@&% 9*'+rF   r   c                     [        U SS5      b0  U R                  nSR                  UR                  UR                  S9$ [        U SS5      b0  U R
                  nSR                  UR                  UR                  S9$ g)zHReturn a human-readable string representing an invalid matrix dimension.androidDeviceNz[OS-version {vers} on {model}])modelvers	iosDevicez[unknown-environment])getattrr   rT   androidModelIdandroidVersionIdr   
iosModelIdiosVersionId)rP   devices     rC   rO   rO   7  s    [/40<&&F,33##&*A*A 4 C D[+t,8""F,33f&9&9 4 ; < 
!rF   c                      SR                  U S9$ )a%  Reformat a Duration arg to work around ApiTools non-support of that type.

Duration args are normally converted to an int in seconds (e.g. --timeout 5m
becomes args.timeout with int value 300). Duration proto fields are converted
to type string during discovery doc creation, so we have to convert the int
back into a string-formatted Duration (i.e. append an 's') before
passing it to the Testing Service.

Args:
  duration: {int} the number of seconds in the time duration.

Returns:
  String representation of the Duration with units of seconds.
z{secs}s)secs)rT   )durations    rC   ReformatDurationr   E  s     
		x		((rF   )r   
__future__r   r   r   r   r   r   apitools.base.pyr   r   $googlecloudsdk.api_lib.firebase.testr   googlecloudsdk.callioper   googlecloudsdk.corer   r	   googlecloudsdk.core.consoler
   r   r(   rg   objectr   rO   r   r   rF   rC   <module>r      sZ    H &  '    > ; 5 E # * 2 
 #  MF M`!)rF   