
    ^                        S 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SKrSSKrSSK	r	SSK
r
SSKrSSKrSSKJ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Jr  SSKJr  SSKJs  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r*S\RV                  " S5      -   S-   r,S r-S r. " S S\/5      r0S5S jr1S5S jr2S5S  jr3S5S! jr4S" r5S# r6S5S$ jr7S% r8S5S& jr9S5S' jr:S( r; " S) S*\	Rx                  5      r= " S+ S,\5      r> " S- S.\>5      r? " S/ S0\ R                  5      rA\&R                  " 5       rC " S1 S2\ R                  5      rD " S3 S4\A5      rEg)6z,Unit tests for gsutil parallelism framework.    )absolute_import)print_function)division)unicode_literalsN)mock)BucketStorageUri)
StorageUri)
cs_api_map)command)Command)CreateOrGetGsutilLogger)DummyArgChecker)MockCloudApi)MockLoggingHandler)RequiresIsolation)unittest)$CheckMultiprocessingAvailableAndInit)multiprocessing_context)IS_OSX
IS_WINDOWSx   
z==> NOTE: You are performing a sequence of gsutil operations that may run significantly faster if you instead use gsutil -m fake ...
Please see the -m section under "gsutil help options" for further information about when gsutil -m can be advantageous.c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )z2Decorator used to provide a timeout for functions.c                  F  > [         (       dC  [        R                  " [        R                  [        5        [        R                  " [
        5         T" U 0 UD6  [         (       d  [        R                  " S5        g g ! [         (       d  [        R                  " S5        f f = fNr   )r   signalSIGALRM_HandleAlarmalarm_TEST_TIMEOUT_SECONDS)argskwargsfuncs     9platform/gsutil/gslib/tests/test_parallelism_framework.pyWrapperTimeout.<locals>.WrapperG   sd    :mmFNNL1ll()
DFZQ ZZQ s   A< <$B )	functoolswraps)r$   r&   s   ` r%   Timeoutr*   D   s'     ??4  
.    c                     [        S5      e)NzTest timed out.)	Exception)
signal_numcur_stack_frames     r%   r   r   V   s    #$$r+   c                   (   ^  \ rS rSrU 4S jrSrU =r$ )CustomExceptionZ   c                 ,   > [         [        U ]  U5        g N)superr1   __init__)selfexception_str	__class__s     r%   r6   CustomException.__init__\   s    	/4)-8r+    __name__
__module____qualname____firstlineno__r6   __static_attributes____classcell__r9   s   @r%   r1   r1   Z   s    9 9r+   r1   c                     gN   r;   clsr"   thread_states      r%   _ReturnOneValuerJ   `   s    	
r+   c                 j    [         R                  " 5       [        R                  " 5       R                  4$ r4   )osgetpid	threadingcurrent_threadidentrG   s      r%   _ReturnProcAndThreadIdrQ   d   s"    	i..066	66r+   c                 B    [         R                  " S5        [        XUS9$ )N   )rI   )timesleeprQ   rG   s      r%   _SleepThenReturnProcAndThreadIdrV   h   s     **Q-		EEr+   c                     [        S5      e)NzFailing on purpose.)r1   rG   s      r%   _FailureFuncrX   p   s    -..r+   c                 B    U =R                   S-  sl         [        S5      e)NrF   z%Exception handler failing on purpose.)failure_countr1   rH   es     r%   _FailingExceptionHandlerr]   t   s    q?@@r+   c                 d    U R                   R                  U5        U =R                  S-  sl        g rE   )logger	exceptionrZ   r[   s     r%   _ExceptionHandlerra   y   s%    **qqr+   c                 @    U =R                   [        U5      -  sl         g r4   )arg_length_sumlenrG   s      r%   _IncrementByLengthre   ~   s    D	!r+   c                     [         (       a  gU $ rE   r   )process_counts    r%   _AdjustProcessCountIfWindowsrh      s    Zr+   c           
          U/S-  n[        US   5      nUS   nU R                  [        U[        [        UUSS9n[        U5      nU R                  [        U[        [        UUSS9n[        U5      U-   $ )a{  Calls Apply with arguments repeated seven times.

The first two elements of args should be the process and thread counts,
respectively, to be used for the recursive calls.

Args:
  cls: The Command class to call Apply on.
  args: Arguments to pass to Apply.
  thread_state: Unused, required by function signature.

Returns:
  Number of values returned by the two calls to Apply.
   r   rF   Targ_checkerrg   thread_countshould_return_results)rh   Apply_PerformNRecursiveCallsra   r   sumrJ   rd   )rH   r"   rI   new_argsrg   rm   return_valuesrets           r%   _ReApplyWithReplicatedArgumentsru      s     VaZ(.tAw7-a,))3$-(7*7)526  8- 	M#))O$-(7*7)526  8- 
]	c	!!r+   c           
          [        US   5      nUS   nU R                  [        S/US   -  [        [        UUSS9n[        U5      $ )a  Calls Apply to perform N recursive calls.

The first two elements of args should be the process and thread counts,
respectively, to be used for the recursive calls, while N is the third element
(the number of recursive calls to make).

Args:
  cls: The Command class to call Apply on.
  args: Arguments to pass to Apply.
  thread_state: Unused, required by function signature.

Returns:
  Number of values returned by the call to Apply.
r   rF   r;      Trk   )rh   ro   rJ   ra   r   rd   )rH   r"   rI   rg   rm   rs   s         r%   rp   rp      sX     /tAw7-a,))ObTDG^-(7*7)526  8- 
]	r+   c                     US-  S:g  $ )Nrw   r   r;   )rH   args     r%   _SkipEvenNumbersArgCheckerrz      s    	qAr+   c                   &    \ rS rSrS rS rS rSrg)FailingIterator   c                 *    Xl         X l        SU l        g r   )sizefailure_indicescurrent_index)r7   r   r   s      r%   r6   FailingIterator.__init__   s    I*Dr+   c                     U $ r4   r;   r7   s    r%   __iter__FailingIterator.__iter__   s    Kr+   c                 "   U R                   U R                  :X  a  [        S5      eU R                   U R                  ;   a-  U =R                   S-  sl         [	        SU R                   -  5      eU =R                   S-  sl         U R                   S-
  $ )N rF   z(Iterator failing on purpose at index %d.)r   r   StopIterationr   r1   r   s    r%   __next__FailingIterator.__next__   s    TYY&"			t33	3
AF ../ 0 0 A!##r+   )r   r   r   N)r=   r>   r?   r@   r6   r   r   rA   r;   r+   r%   r|   r|      s    
	$r+   r|   c            	       j    \ rS rSrSr\R                  " S/ S9r\R                  " S/ SSS0 S9r	S	 r
S
rg)FakeCommand   z9Fake command class for overriding command instance state.fake)command_name_aliasescommand_helpzSomething to take up space.z Something else to take up space.)	help_namehelp_name_aliases	help_typehelp_one_line_summary	help_textsubcommand_help_textc                 h   [         U l        S/S/S.nSSS.n[        R                  R	                  [        R
                  X#5      U l        [        S5      U l        Xl	        SU l
        [        5       U l        [        5       R                  U l        SU l        0 U l        S U l        S U l        S U l        g )NJSONXML)gss3r   r   )r   bucket_storage_uri_classr
   GsutilApiMapFactory	GetApiMapGsutilApiClassMapFactorygsutil_api_mapr   r_   parallel_operationsrZ   r   
gsutil_apir   is_availablemultiprocessing_is_availabledebugnon_metadata_headersperf_trace_tokentrace_tokenuser_project)r7   do_parallelsupport_mapdefault_maps       r%   r6   FakeCommand.__init__   s    $4D! %1Ku-K$88BB++[GD)-8DK*D"nDO,.;; 	%DJ "D DDDr+   )r   r   rZ   r   r   r_   r   r   r   r   r   r   N)r=   r>   r?   r@   __doc__r   CreateCommandSpeccommand_specHelpSpec	help_specr6   rA   r;   r+   r%   r   r      sD    A**,
 92)r+   r   c                   (   ^  \ rS rSrU 4S jrSrU =r$ )'FakeCommandWithoutMultiprocessingModulei  c                 :   > [         [        U ]  U5        SU l        g )NF)r5   r   r6   r   )r7   r   r9   s     r%   r6   0FakeCommandWithoutMultiprocessingModule.__init__  s    	
14A+N(-D%r+   )r   r<   rC   s   @r%   r   r     s    . .r+   r   c                   L
   \ rS rSrSr\rSSSS\4S jr\	S 5       r
\	S 5       r\	\R                  " \S5      S	 5       5       r\	\R                  " \S5      S
 5       5       r\S 5       r\	S 5       r\	S 5       r\	\R                  " \S5      S 5       5       r\	\R                  " \S5      S 5       5       r\S 5       r\	\R                  " \S5      S 5       5       r\	S 5       r\	\R                  " \S5      S 5       5       r\	S 5       r\	S 5       r\	S 5       r\	\R                  " \S5      S 5       5       r\	\R                  " \S5      S 5       5       r\S 5       r \	S 5       r!\	S 5       r"\	\R                  " \S5      S 5       5       r#\	\R                  " \S5      S 5       5       r$\S 5       r%\	S 5       r&\	S  5       r'\	\R                  " \S5      S! 5       5       r(\	\R                  " \S5      S" 5       5       r)\S# 5       r*\	S$ 5       r+\	S% 5       r,\	\R                  " \S5      S& 5       5       r-\	\R                  " \S5      S' 5       5       r.\S( 5       r/\	\S) 5       5       r0\	S* 5       r1\	S+ 5       r2\	\R                  " \S5      S, 5       5       r3\	\R                  " \S5      S- 5       5       r4\	\Rj                  " \6S.5      S/ 5       5       r7\	\R                  " \6S05      \R                  " \S5      S1 5       5       5       r8\	S2 5       r9\S3 5       r:\	S4 5       r;\	S5 5       r<\	\R                  " \S5      S6 5       5       r=\	\R                  " \S5      S7 5       5       r>\S8 5       r?\	S9 5       r@\	S: 5       rA\	\R                  " \S5      S; 5       5       rB\	\R                  " \S5      S< 5       5       rC\S= 5       rD\ER                  R                  \HS>S?5      \ER                  R                  \HS@SASB9SC 5       5       rI\ER                  R                  \HS>SA5      \ER                  R                  \HSDSE5      \ER                  R                  \HS@SASB9SF 5       5       5       rJ\ER                  R                  \HS>SA5      \ER                  R                  \HSDSE5      \ER                  R                  \HS@S?SB9SG 5       5       5       rK\ER                  R                  \HS>SA5      \ER                  R                  \HSDSE5      \ER                  R                  \HS@SHSB9SI 5       5       5       rLSJ rMSKrNg)LTestParallelismFrameworki  z(gsutil parallelism framework test suite.NFc
                     U=(       d    U R                  S5      nU=(       d    [        n
UR                  UUU
UUU	SUUS9	$ )NT)rm   rg   rl   rn   shared_attrsfail_on_error)command_classra   ro   )r7   r$   args_iteratorrg   rm   command_instr   r   thr_exc_handlerrl   exception_handlers              r%   	_RunApply"TestParallelismFramework._RunApply  sW      ;4#5#5d#;L'<+<d+/+7,9*548+7,9  ; ;r+   c                 (    U R                  SS5        g rE   _TestBasicApplyr   s    r%   'testBasicApplySingleProcessSingleThread@TestParallelismFramework.testBasicApplySingleProcessSingleThread*      Ar+   c                 (    U R                  SS5        g NrF      r   r   s    r%   &testBasicApplySingleProcessMultiThread?TestParallelismFramework.testBasicApplySingleProcessMultiThread.  r   r+   +Multiprocessing is not supported on Windowsc                 (    U R                  SS5        g Nr   rF   r   r   s    r%   &testBasicApplyMultiProcessSingleThread?TestParallelismFramework.testBasicApplyMultiProcessSingleThread2       	Ar+   c                 (    U R                  SS5        g Nr   r   r   s    r%   %testBasicApplyMultiProcessMultiThread>TestParallelismFramework.testBasicApplyMultiProcessMultiThread7  r   r+   c                     S/SU-  U-  S-   -  nU R                  [        X1U5      nU R                  [        U5      [        U5      5        g )Nr;      rF   )r   rJ   assertEqualrd   r7   rg   rm   r"   resultss        r%   r   (TestParallelismFramework._TestBasicApply<  sG    42%4q89Dnn_d<PGSYG-r+   c                 (    U R                  SS5        g rE   _TestApplyWithNoTasksr   s    r%   $testNoTasksSingleProcessSingleThread=TestParallelismFramework.testNoTasksSingleProcessSingleThreadC      q!$r+   c                 (    U R                  SS5        g r   r   r   s    r%   #testNoTasksSingleProcessMultiThread<TestParallelismFramework.testNoTasksSingleProcessMultiThreadG  r   r+   c                 (    U R                  SS5        g r   r   r   s    r%   #testNoTasksMultiProcessSingleThread<TestParallelismFramework.testNoTasksMultiProcessSingleThreadK       	q!$r+   c                 (    U R                  SS5        g r   r   r   s    r%   "testNoTasksMultiProcessMultiThread;TestParallelismFramework.testNoTasksMultiProcessMultiThreadP  r   r+   c                     S/n[        X-  S-   5       H  nU R                  [        X1U5        M     U R                  X5        g)zATests that calling Apply with no tasks releases locks/semaphores.r;   rF   N)ranger   rJ   r   )r7   rg   rm   
empty_args_s        r%   r   .TestParallelismFramework._TestApplyWithNoTasksU  sB     J=/!34
nn_jN 5 	5r+   c                 (    U R                  SS5        g r   /_TestApplySaturatesAvailableProcessesAndThreadsr   s    r%   *testApplySaturatesMultiProcessSingleThreadCTestParallelismFramework.testApplySaturatesMultiProcessSingleThread`       	88A>r+   c                 (    U R                  SS5        g r   r   r   s    r%   *testApplySaturatesSingleProcessMultiThreadCTestParallelismFramework.testApplySaturatesSingleProcessMultiThreade  s    88A>r+   c                 (    U R                  SS5        g r   r   r   s    r%   )testApplySaturatesMultiProcessMultiThreadBTestParallelismFramework.testApplySaturatesMultiProcessMultiThreadi  r   r+   c                 t   SnS/X-  U-  -  nUnU R                  S5      R                  (       d  X1-  nU R                  [        UX5      n0 nU H  u  pUR	                  X4S5      S-   XxU	4'   M!     [
        R                  " U5       H-  u  pU R                  XSU
S   < SU
S   < SU< S	U< 35        M/     g
)z<Tests that created processes and threads evenly share tasks.rw   r;   Tr   rF   zProcess z thread z completed z tasks. Expected: N)r   r   r   rV   getsix	iteritemsr   )r7   rg   rm   calls_per_threadr"   expected_calls_per_threadr   
usage_dict
process_id	thread_idid_tuplenum_tasks_completeds               r%   r   HTestParallelismFramework._TestApplySaturatesAvailableProcessesAndThreadsn  s     4=/2BBCD 0d#@@ #3"Bnn<d*:GJ#*-7^^
!1.&().*ji() $+ ,/==+D'

8A;%8$&' ,Er+   c                 (    U R                  SS5        g rE   _TestIteratorFailurer   s    r%   ,testIteratorFailureSingleProcessSingleThreadETestParallelismFramework.testIteratorFailureSingleProcessSingleThread      a#r+   c                 (    U R                  SS5        g r   r  r   s    r%   +testIteratorFailureSingleProcessMultiThreadDTestParallelismFramework.testIteratorFailureSingleProcessMultiThread  r  r+   c                 (    U R                  SS5        g r   r  r   s    r%   +testIteratorFailureMultiProcessSingleThreadDTestParallelismFramework.testIteratorFailureMultiProcessSingleThread       	a#r+   c                 (    U R                  SS5        g r   r  r   s    r%   *testIteratorFailureMultiProcessMultiThreadCTestParallelismFramework.testIteratorFailureMultiProcessMultiThread  r  r+   c                    [        SS/5      nU R                  [        X1U5      nU R                  S[	        U5      5        [        SS/5      nU R                  [        X1U5      nU R                  S[	        U5      5        [        SS/5      nU R                  [        X1U5      nU R                  S[	        U5      5        X-  S:  a?  [        SS/5      nU R                  [        UUUSS9nU R                  S[	        U5      5        [        S[        S5      5      nU R                  [        X1U5      nU R                  S[	        U5      5        [        S/ 5      nU R                  [        X1U5      nU R                  S[	        U5      5        g)	z$Tests apply with a failing iterator.
   r   	   rS   rF   Tr   N)r|   r   rJ   r   rd   r   r   s        r%   r  -TestParallelismFramework._TestIteratorFailure  sX   
 2s#Dnn_d<PGQG%2s#Dnn_d<PGQG%2s#Dnn_d<PGQG%#a'R!%d#,+-1	  3g
 q#g,'2uRy)Dnn_d<PGQG%1b!Dnn_d<PGQG%r+   c                 (    U R                  SS5        g rE   _TestSharedAttrsWorkr   s    r%   0testTestSharedAttrsWorkSingleProcessSingleThreadITestParallelismFramework.testTestSharedAttrsWorkSingleProcessSingleThread  r  r+   c                 (    U R                  SS5        g r   r"  r   s    r%   /testTestSharedAttrsWorkSingleProcessMultiThreadHTestParallelismFramework.testTestSharedAttrsWorkSingleProcessMultiThread  r  r+   c                 (    U R                  SS5        g r   r"  r   s    r%   /testTestSharedAttrsWorkMultiProcessSingleThreadHTestParallelismFramework.testTestSharedAttrsWorkMultiProcessSingleThread  r  r+   c                 (    U R                  SS5        g r   r"  r   s    r%   .testTestSharedAttrsWorkMultiProcessMultiThreadGTestParallelismFramework.testTestSharedAttrsWorkMultiProcessMultiThread  r  r+   c                 >   U R                  S5      nSUl        SSS// SS// S/nU R                  [        UUUUS	/S
9  SnU H  nU[	        U5      -  nM     U R                  XSR                  5        [        SS/5      S4[        S/ SQ5      S4[        SS/5      S44 H{  u  nnU R                  S5      nUnU R                  [        UUUUS/S
9  U R                  UUR                  SU< SUR                  < SUR                  < SUR                  < 3S9  M}     g)z0Tests that Apply successfully uses shared_attrs.T   foobarbazxyabcdrc   )r   r   rS   r   rF   r  rF   r   rS   r      rZ   z'Failure count did not match. Expected: z
, actual: z for failing iterator of size z, failing indices )msgN)r   rc   r   re   rd   r   r|   rJ   rZ   r   r   )	r7   rg   rm   r   r"   expected_sumry   failing_iteratorexpected_failure_counts	            r%   r#  -TestParallelismFramework._TestSharedAttrsWork  s_    %%d+L"$LE5>2Sz2v>DNN%  ,!1 2  4 Lc#hl \#>#>?
 '6a!&=&'&)+:2y+I1*M&5a!&=q%A%C	!		 ''-ld
nn_"!".#2"3  5 
 

$
$ "<#=#=  "2"B"BD  E%Cr+   c                 (    U R                  SS5        g rE   #_TestThreadsSurviveExceptionsInFuncr   s    r%   ;testThreadsSurviveExceptionsInFuncSingleProcessSingleThreadTTestParallelismFramework.testThreadsSurviveExceptionsInFuncSingleProcessSingleThread      ,,Q2r+   c                 (    U R                  SS5        g r   r?  r   s    r%   :testThreadsSurviveExceptionsInFuncSingleProcessMultiThreadSTestParallelismFramework.testThreadsSurviveExceptionsInFuncSingleProcessMultiThread  rC  r+   c                 (    U R                  SS5        g r   r?  r   s    r%   :testThreadsSurviveExceptionsInFuncMultiProcessSingleThreadSTestParallelismFramework.testThreadsSurviveExceptionsInFuncMultiProcessSingleThread       	,,Q2r+   c                 (    U R                  SS5        g r   r?  r   s    r%   9testThreadsSurviveExceptionsInFuncMultiProcessMultiThreadRTestParallelismFramework.testThreadsSurviveExceptionsInFuncMultiProcessMultiThread  rJ  r+   c           
          U R                  S5      nS/S-  nU R                  [        UUUUS/[        S9  U R	                  [        U5      UR                  5        g NTr;   rS   rZ   )r   r   r   r   r   rX   r]   r   rd   rZ   r7   rg   rm   r   r"   s        r%   r@  <TestParallelismFramework._TestThreadsSurviveExceptionsInFunc	  a    %%d+LD1HDNN<  ,!0 1#;  = 	SY : :;r+   c                 (    U R                  SS5        g rE   &_TestThreadsSurviveExceptionsInHandlerr   s    r%   >testThreadsSurviveExceptionsInHandlerSingleProcessSingleThreadWTestParallelismFramework.testThreadsSurviveExceptionsInHandlerSingleProcessSingleThread      //15r+   c                 (    U R                  SS5        g r   rU  r   s    r%   =testThreadsSurviveExceptionsInHandlerSingleProcessMultiThreadVTestParallelismFramework.testThreadsSurviveExceptionsInHandlerSingleProcessMultiThread  rY  r+   c                 (    U R                  SS5        g r   rU  r   s    r%   =testThreadsSurviveExceptionsInHandlerMultiProcessSingleThreadVTestParallelismFramework.testThreadsSurviveExceptionsInHandlerMultiProcessSingleThread       	//15r+   c                 (    U R                  SS5        g r   rU  r   s    r%   <testThreadsSurviveExceptionsInHandlerMultiProcessMultiThreadUTestParallelismFramework.testThreadsSurviveExceptionsInHandlerMultiProcessMultiThread#  r`  r+   c           
          U R                  S5      nS/S-  nU R                  [        UUUUS/[        S9  U R	                  [        U5      UR                  5        g rO  rP  rQ  s        r%   rV  ?TestParallelismFramework._TestThreadsSurviveExceptionsInHandler(  rS  r+   c                    ^  U 4S jnU 4S jnU" U5        U 4S jnU" U5        U 4S jnU" U5        U 4S jnU" U5        U 4S jnU" U5        g)zCTests that fail_on_error produces the correct exception on failure.c                    >  U " 5         TR                  S5        g ! [         a
  n S nAg S nAf[         a'  nTR                  S[        U5      -   5         S nAg S nAff = f)Nz=Setting fail_on_error should raise any exception encountered.zGot unexpected error: )failr1   r-   str)	test_funcr\   r7   s     r%   _ExpectCustomExceptionLTestParallelismFramework.testFailOnErrorFlag.<locals>._ExpectCustomException:  sR    5		K	M  5		*SV3445s    
AAAAc            
      h   > TR                  S5      n S/S-  nTR                  [        USSU S/SS9  g )NTr;   rS   rF   rZ   )r   r   r   )r   r   rX   )r   r"   r7   s     r%   _RunFailureFuncETestParallelismFramework.testFailOnErrorFlag.<locals>._RunFailureFuncD  sF    ''-ldQhd
nn\".#2"3#'  )r+   c                     > [        SS/5      n TR                  [        U SSSS9nTR                  S[	        U5      5        g )Nr  r   rF   Tr  r|   r   rJ   r   rd   r"   r   r7   s     r%    _RunFailingIteratorFirstPositionVTestParallelismFramework.testFailOnErrorFlag.<locals>._RunFailingIteratorFirstPositionQ  =    R!%da$Og
q#g,'r+   c                     > [        SS/5      n TR                  [        U SSSS9nTR                  S[	        U5      5        g )Nr  rS   rF   Tr  rq  rr  s     r%   )_RunFailingIteratorPositionMiddlePosition_TestParallelismFramework.testFailOnErrorFlag.<locals>._RunFailingIteratorPositionMiddlePositionX  ru  r+   c                     > [        SS/5      n TR                  [        U SSSS9nTR                  S[	        U5      5        g )Nr  r  rF   Tr  rq  rr  s     r%   _RunFailingIteratorLastPositionUTestParallelismFramework.testFailOnErrorFlag.<locals>._RunFailingIteratorLastPosition_  ru  r+   c                     > [        S/ SQ5      n TR                  [        U SSSS9nTR                  S[	        U5      5        g )Nr  r7  rF   Tr  rq  rr  s     r%   $_RunFailingIteratorMultiplePositionsZTestParallelismFramework.testFailOnErrorFlag.<locals>._RunFailingIteratorMultiplePositionsf  s;    R+da$Og
q#g,'r+   Nr;   )r7   rk  rn  rs  rw  rz  r}  s   `      r%   testFailOnErrorFlag,TestParallelismFramework.testFailOnErrorFlag5  sW    
5	) ?+(
 ;<(
 DE(
 :;(
 ?@r+   c                 (    U R                  SS5        g rE   *_TestRecursiveDepthThreeDifferentFunctionsr   s    r%   BtestRecursiveDepthThreeDifferentFunctionsSingleProcessSingleThread[TestParallelismFramework.testRecursiveDepthThreeDifferentFunctionsSingleProcessSingleThreadm      33Aq9r+   c                 (    U R                  SS5        g r   r  r   s    r%   AtestRecursiveDepthThreeDifferentFunctionsSingleProcessMultiThreadZTestParallelismFramework.testRecursiveDepthThreeDifferentFunctionsSingleProcessMultiThreadq  r  r+   c                 (    U R                  SS5        g r   r  r   s    r%   AtestRecursiveDepthThreeDifferentFunctionsMultiProcessSingleThreadZTestParallelismFramework.testRecursiveDepthThreeDifferentFunctionsMultiProcessSingleThreadu       	33Aq9r+   c                 (    U R                  SS5        g r   r  r   s    r%   @testRecursiveDepthThreeDifferentFunctionsMultiProcessMultiThreadYTestParallelismFramework.testRecursiveDepthThreeDifferentFunctionsMultiProcessMultiThreadz  r  r+   z,This warning should only be printed on MacOSc                 4   [        S5      n[        5       nUR                  U5        U R                  SS5        SnUR                  S    Vs/ s H  nUR                  U5      PM     nnU R                  [        U5      5        UR                  U5        g s  snf Nr   r   8If you experience problems with multiprocessing on MacOSinfo)	r   r   
addHandlerr  messages
startswith
assertTrueanyremoveHandlerr7   r_   mock_log_handlermacos_messagemessagecontains_messages         r%   #testMacOSLogsMultiprocessingWarning<TestParallelismFramework.testMacOSLogsMultiprocessingWarning  s     %]3F)+
&'33Aq9NM (0088G 	=)8   	OOC()*
)*   Bz'This warning should be printed on MacOSc                 4   [        S5      n[        5       nUR                  U5        U R                  SS5        SnUR                  S    Vs/ s H  nUR                  U5      PM     nnU R                  [        U5      5        UR                  U5        g s  snf r  	r   r   r  r  r  r  assertFalser  r  r  s         r%   ,testNonMacOSDoesNotLogMultiprocessingWarningETestParallelismFramework.testNonMacOSDoesNotLogMultiprocessingWarning  s     %]3F)+
&'33Aq9NM (0088G 	=)8   	S)*+
)*r  c                 4   [        S5      n[        5       nUR                  U5        U R                  SS5        SnUR                  S    Vs/ s H  nUR                  U5      PM     nnU R                  [        U5      5        UR                  U5        g s  snf )Nr   rF   r   r  r  r  r  s         r%   (testMultithreadingDoesNotLogMacOSWarningATestParallelismFramework.testMultithreadingDoesNotLogMacOSWarning  s    $]3F)+
&'33Aq9NM (0088G 	=)8   	S)*+
)*r  c                     / SQnU Vs/ s H  oAX$/PM     nnU R                  [        UX5      nU R                  S[        U5      [	        U5      -   -  [        U5      5        gs  snf )zTests recursive application of Apply.

Calls Apply(A), where A calls Apply(B) followed by Apply(C) and B calls
Apply(C).

Args:
  process_count: Number of processes to use.
  thread_count: Number of threads to use.
)r   rF   r8  rF   rS   rj   N)r   ru   r   rq   rd   )r7   rg   rm   	base_argscountr"   r   s          r%   r  CTestParallelismFramework._TestRecursiveDepthThreeDifferentFunctions  sb      I>GHiUL0iDHnn<d*:GQ#i.3y>9:CLI	 Is   A#c                 (    U R                  SS5        g rE   +_TestExceptionInProducerRaisesAndTerminatesr   s    r%   CtestExceptionInProducerRaisesAndTerminatesSingleProcessSingleThread\TestParallelismFramework.testExceptionInProducerRaisesAndTerminatesSingleProcessSingleThread      44Q:r+   c                 (    U R                  SS5        g r   r  r   s    r%   BtestExceptionInProducerRaisesAndTerminatesSingleProcessMultiThread[TestParallelismFramework.testExceptionInProducerRaisesAndTerminatesSingleProcessMultiThread  r  r+   c                 (    U R                  SS5        g r   r  r   s    r%   BtestExceptionInProducerRaisesAndTerminatesMultiProcessSingleThread[TestParallelismFramework.testExceptionInProducerRaisesAndTerminatesMultiProcessSingleThread       	44Q:r+   c                 (    U R                  SS5        g r   r  r   s    r%   AtestExceptionInProducerRaisesAndTerminatesMultiProcessMultiThreadZTestParallelismFramework.testExceptionInProducerRaisesAndTerminatesMultiProcessMultiThread  r  r+   c                 z    U n U R                  [        X1U5        U R                  S5        g ! [         a     g f = f)Nz!Did not raise expected exception.)r   rJ   rh  	TypeError)r7   rg   rm   r"   s       r%   r  DTestParallelismFramework._TestExceptionInProducerRaisesAndTerminates  s=     D
nn_d<H
ii34 
s   (- 
::c                 (    U R                  SS5        g rE   _TestSkippedArgumentsr   s    r%   -testSkippedArgumentsSingleThreadSingleProcessFTestParallelismFramework.testSkippedArgumentsSingleThreadSingleProcess  r   r+   c                 (    U R                  SS5        g r   r  r   s    r%   ,testSkippedArgumentsMultiThreadSingleProcessETestParallelismFramework.testSkippedArgumentsMultiThreadSingleProcess  r   r+   c                 (    U R                  SS5        g r   r  r   s    r%   ,testSkippedArgumentsSingleThreadMultiProcessETestParallelismFramework.testSkippedArgumentsSingleThreadMultiProcess  r   r+   c                 (    U R                  SS5        g r   r  r   s    r%   +testSkippedArgumentsMultiThreadMultiProcessDTestParallelismFramework.testSkippedArgumentsMultiThreadMultiProcess  r   r+   c                    SU-  U-  n[        SUS-   5      nU R                  [        UUU[        S9nU R	                  US-  [        U5      5        U R	                  US-  [        U5      5        U Vs/ s H  nSU-  PM
     nnU R                  [        UUU[        S9nU R	                  S[        U5      5        g s  snf )Nrw   rF   )rl   r   )r   r   rJ   rz   r   rd   rq   )r7   rg   rm   nr"   r   r4  s          r%   r  .TestParallelismFramework._TestSkippedArguments  s     	
ML(AAE?Dnn_!*))C	  EG
 	QUCL)QUCL)   4aAE4D nn_!*))C	  EG
 	QG% !s   3B;#OFFER_GSUTIL_M_SUGGESTION_THRESHOLDrw   GetTermLinesd   )return_valuec                 H   SUl         [        S5      n[        5       nUR                  U5        U R	                  [
        [        S5      SSS9  UR                  S    Vs/ s H  nU[        :H  PM     nnU R                  [        U5      5        UR                  U5        g s  snf )Nr  r   rw   rF   rg   rm   r  )r  r   r   r  r   rJ   r   r  PARALLEL_PROCESSING_MESSAGEr  r  r  r7   mock_get_term_linesr_   r  r  r  s         r%   6testSequentialApplyRecommendsParallelismAfterThresholdOTestParallelismFramework.testSequentialApplyRecommendsParallelismAfterThreshold
  s     (+$$]3F)+
&'NN?E!HAANN (0088G 	..8   	OOC()*
)*s   B#OFFER_GSUTIL_M_SUGGESTION_FREQUENCYr  c                 <   [        S5      n[        5       nUR                  U5        U R                  [        [        S5      SSS9  UR                  S    Vs/ s H  nU[        :H  PM     nnU R                  [        U5      S5        UR                  U5        g s  snf )Nr      rF   r  r  r   r   r   r  r   rJ   r   r  r  r   rq   r  r  s         r%   =testSequentialApplyRecommendsParallelismAtSuggestionFrequencyVTestParallelismFramework.testSequentialApplyRecommendsParallelismAtSuggestionFrequency      
 %]3F)+
&'NN?E"IQQNO (0088G 	..8   	S)*A.
)*   Bc                 <   [        S5      n[        5       nUR                  U5        U R                  [        [        S5      SSS9  UR                  S    Vs/ s H  nU[        :H  PM     nnU R                  [        U5      S5        UR                  U5        g s  snf )Nr      rF   r  r  r   r  r  s         r%   HtestSequentialApplyRecommendsParallelismAtEndIfLastSuggestionIsOutOfViewaTestParallelismFramework.testSequentialApplyRecommendsParallelismAtEndIfLastSuggestionIsOutOfView.  r  r  r   c                 <   [        S5      n[        5       nUR                  U5        U R                  [        [        S5      SSS9  UR                  S    Vs/ s H  nU[        :H  PM     nnU R                  [        U5      S5        UR                  U5        g s  snf )Nr   r  rF   r  r  rw   r  r  s         r%   ItestSequentialApplyDoesNotRecommendParallelismAtEndIfLastSuggestionInViewbTestParallelismFramework.testSequentialApplyDoesNotRecommendParallelismAtEndIfLastSuggestionInView@  r  r  c                    [         R                  " [        R                  R                  R
                  S9[        l        S[         R                  " [        R                  R                  R
                  S90[        l        U R                  S5      R                  5         U R                  [        R                  5        U R                  [        R                  5        g )N)specr   T)r   Mockbotor   
connectionS3Connectionr	   provider_poolr   _ResetConnectionPoolassertIsNoner  r   s    r%   -testResetConnectionPoolDeletesConnectionStateFTestParallelismFramework.testResetConnectionPoolDeletesConnectionStateR  s     II477+=+=+J+JKJdiiTWW//<<= J 	t113j++,Z--.r+   r;   )Or=   r>   r?   r@   r   r   r   r   r   r   r   r   r   skipIfr   r   r   r*   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r$  r'  r*  r-  r#  rA  rE  rH  rL  r@  rW  r[  r^  rb  rV  r  r  r  r  r  
skipUnlessr   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   patchobjectr   r  r  r  r  r  rA   r;   r+   r%   r   r     s   0- "!# $+;.     ??:LM N  ??:LM N  . . % % % % ??:LM% N % ??:LM% N % 6 6 ??:LM? N ? ? ? ??:LM? N ? ' '4 $ $ $ $ ??:LM$ N $ ??:LM$ N $  &  &D $ $ $ $ ??:LM$ N $ ??:LM$ N $ $E $EL 3 3 3 3 ??:LM3 N 3 ??:LM3 N 3 
< 
< 6 6 6 6 ??:LM6 N 6 ??:LM6 N 6 
< 
< 
4A  4Al : : : : ??:LM: N : ??:LM: N : vMN+ O + ??6DE??:LM+ N F + + + J J$ ; ; ; ; ??:LM; N ; ??:LM; N ;   % % % % ??:LM% N % ??:LM% N % & &, ::WCQG::Wn3?+ @ H+  ::WCSI::WCRH::Wn3?+ @ I J+ ::WCSI::WCRH::Wn1=+ > I J+ ::WCSI::WCRH::Wn1=+ > I J+	/r+   r   c            	           \ rS rSrSr\\R                  R                  \	S\
R                  " \R                  S5      S9\R                  " \S5      S 5       5       5       rSrg)	+TestParallelismFrameworkWithMultiprocessingic  z1Tests that only run with multiprocessing enabled.r  N)side_effectr   c           	          Sn[        S5      R                  [        / SQ[        US[        S9  [        U5       H%  nU R                  [        R                  SS95        M'     g )Nrw   T)rF   rw   r   r   )rg   rm   rl   g      ?)timeout)	r   ro   rJ   ra   r   r   r  
call_queuer  )r7   mock_reset_connection_poolexpected_call_countr   s       r%   +testResetConnectionPoolCalledOncePerProcessWTestParallelismFrameworkWithMultiprocessing.testResetConnectionPoolCalledOncePerProcessf  s]     OY-*=)*(7	  9 &'

s34 (r+   r;   )r=   r>   r?   r@   r   r   r   r  r  r   r(   partialr  putr   r  r   r  rA   r;   r+   r%   r  r  c  se    9::[+!*!2!2:>>4!H  J ??:LM
5 NJ 

5r+   r  c                       \ rS rSrSr\rSrg).TestParallelismFrameworkWithoutMultiprocessingix  a5  Tests parallelism framework works with multiprocessing module unavailable.

Notably, this test has no way to override previous calls
to gslib.util.CheckMultiprocessingAvailableAndInit to prevent the
initialization of all of the global variables in command.py, so this still
behaves slightly differently than the behavior one would see on a machine
where the multiprocessing functionality is actually not available (in
particular, it will not catch the case where a global variable that is not
available for the sequential path is referenced before initialization).
r;   N)r=   r>   r?   r@   r   r   r   rA   r;   r+   r%   r	  r	  x  s    	 :-r+   r	  r4   )Fr   
__future__r   r   r   r   r(   rL   r   r  rN   textwraprT   r   r   r  boto.storage_urir   r	   gslibr
   r   gslib.commandr   r   r   gslib.tests.mock_cloud_apir    gslib.tests.mock_logging_handlerr   gslib.tests.testcaseteststestcasegslib.tests.testcase.baser   gslib.tests.util&gslib.utils.parallelism_framework_utilr   r   gslib.utils.system_utilr   r   r!   fillr  r*   r   r-   r1   rJ   rQ   rV   rX   r]   ra   re   rh   ru   rp   rz   Iteratorr|   r   r   GsUtilUnitTestCaser   Queuer  r  r	  r;   r+   r%   <module>r     sQ  , 3 & %  '  	  
      - '   ! 1 ) 3 ? ' ' 7 % W J * .
  #hmm<'=  = @D	 D $%9i 97F/A

"""J4$cll $, '  F.k .M	/x:: M	/d %**,
5(2M2M 5*:5M :r+   