
    8                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZddlZddl	Z	ddl
ZddlmZ ddlmZ ddlmc mZ dd	lmZ d
Z G d dej,                        Zy)z)Unit tests for daisy chain wrapper class.    )absolute_import)print_function)division)unicode_literalsN)DaisyChainWrapper)StorageUrlFromString)TRANSFER_BUFFER_SIZEztest.txtc                        e Zd ZdZdZ ed      Z fdZd Z G d de	j                  j                        Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Z xZS )TestDaisyChainWrapperz+Unit tests for the DaisyChainWrapper class.Nzgs://bucket/objectc                     t         t        |           | j                         | _        t
        j                  j                  | j                        | _        y )N)	superr   setUp_GetTestFiletest_data_fileospathgetsizetest_data_file_len)self	__class__s    7platform/gsutil/gslib/tests/test_daisy_chain_wrapper.pyr   zTestDaisyChainWrapper.setUp*   s=    	
,.++-D ggood.A.ABD    c                     t        j                  ddt        z        }| j                  s| j	                  t        |      | _        | j                  S )Ngslibztests/test_data/%s)	file_namecontents)pkgutilget_data
_TEST_FILE_temp_test_fileCreateTempFile)r   r   s     r   r   z"TestDaisyChainWrapper._GetTestFile/   sM    )=
)JKH!00::B 1 Ddr   c                   "    e Zd ZdZd Z	 	 ddZy)*TestDaisyChainWrapper.MockDownloadCloudApiz9Mock CloudApi that implements GetObjectMedia for testing.c                      || _         d| _        y)aX  Initialize the mock that will be used by the download thread.

      Args:
        write_values: List of values that will be used for calls to write(),
            in order, by the download thread. An Exception class may be part of
            the list; if so, the Exception will be raised after previous
            values are consumed.
      r   N)_write_values	get_calls)r   write_valuess     r   __init__z3TestDaisyChainWrapper.MockDownloadCloudApi.__init__:   s     (ddnr   Nc                     | xj                   dz  c_         d}| j                  D ]P  }||k  r|t        |      z  }|r||k\  r yt        |t              r||j                  |       |t        |      z  }R y)z1Writes self._write_values to the download_stream.   r   N)r&   r%   len
isinstance	Exceptionwrite)	r   unused_bucket_nameunused_object_namedownload_stream
start_byteend_bytekwargs
bytes_readwrite_values	            r   GetObjectMediaz9TestDaisyChainWrapper.MockDownloadCloudApi.GetObjectMediaF   s{     nnnj+++
"
K(
(*

h.
k9-
k*c+&&
 ,r   )r   N)__name__
__module____qualname____doc__r(   r7    r   r   MockDownloadCloudApir#   7   s    C
  #$ $'r   r=   c                     t        |d      5 }	 |j                  t              }|sn|j                  |       *	 ddd       y# 1 sw Y   yxY w)zAWrites all contents from the DaisyChainWrapper to the named file.wbN)openreadr	   r.   )r   daisy_chain_wrapper	file_pathupload_streamdatas        r   _WriteFromWrapperToFilez-TestDaisyChainWrapper._WriteFromWrapperToFile^   sL    	i	-"''(<=
D!	  	 
		s   ,AAc                    g }t        | j                  d      5 }	 |j                  t              }|sn|j	                  |       *	 ddd       | j                         }| j                  | j                  dz   fD ]  }| j                  |      }t        | j                  | j                  ||      }| j                  ||       | j                  |j                  d       t        |d      5 }t        | j                  d      5 }	| j                  |j                         |	j                                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)z&Tests a single call to GetObjectMedia.rbNr*   download_chunk_size)r@   r   rA   r	   appendr!   r   r=   r   
_dummy_urlrF   assertEqualr&   )
r   r'   streamrE   upload_file
chunk_sizemock_apirB   rD   r1   s
             r   testDownloadSingleChunkz-TestDaisyChainWrapper.testDownloadSingleChunkg   sC   L	d!!4	(F{{/0
D!	  	 
) %%'K..0G0G!0KL
**<8h-doo.2.E.E.6BLN ""#6D x))1-T"m$%%t,


=--/1E1E1G
H - #" M 
)	(& -, #"s/   ,E*E/E0EEEEE$	c                    | j                         }g }t        | j                  d      5 }	 |j                  t              }|sn|j                  |       *	 ddd       | j                  |      }t        | j                  | j                  |t              }| j                  ||       | j                  t        z  }| j                  t        z  r|dz  }| j                  |j                  |       t        |d      5 }t        | j                  d      5 }	| j                  |j                         |	j                                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   yxY w)'Tests multiple calls to GetObjectMedia.rH   NrI   r*   )r!   r@   r   rA   r	   rK   r=   r   rL   r   rF   rM   r&   )
r   rO   r'   rN   rE   rQ   rB   num_expected_callsrD   r1   s
             r   testDownloadMultiChunkz,TestDaisyChainWrapper.testDownloadMultiChunk   sO   %%'KL	d!!4	(F{{/0
D!	  	 
) ((6H+0	2
 	  !4kB004HH!55A 	X'');<	k4	 M##T*o++-/C/C/EF + 
!	 ' 
)	(( +* 
!	 s/   ,E;E*/EE*EE'	#E**E3c                    | j                         }g }t        | j                  d      5 }t        dz  dz   }	 |j	                  |      }|sn|j                  |       &	 ddd       | j                  |      }t        | j                  | j                  |t              }| j                  ||       t        j                  | j                  t        z        }| j                  |j                  |       t        |d      5 }	t        | j                  d      5 }
| j                  |	j	                         |
j	                                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   yxY w)rT   rH      
   NrI   )r!   r@   r   r	   rA   rK   r=   r   rL   r   rF   mathceilrM   r&   )r   rO   r'   rN   buffer_write_sizerE   rQ   rB   rU   rD   r1   s              r   "testDownloadWithDifferentChunkSizez8TestDaisyChainWrapper.testDownloadWithDifferentChunkSize   sT   %%'KL	d!!4	(F /2R7{{,-
D!   
) ((6H+0	2
 	  !4kB4#:#:#7$8 9 	X'');<	k4	 M##T*o++-/C/C/EF + 
!	 / 
)	(0 +* 
!	 s/   4E>E-/E!E-E!E*	&E--E6c                    g }t        | j                  d      5 }	 |j                  d       |j                  t              }|j                  d       |sn|j                  |       L	 ddd       | j                         }| j                  |      }t        | j                  | j                  || j                        }| j                  ||       | j                  |j                  d       t        |d      5 }t        | j                  d      5 }| j                  |j                         |j                                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   yxY w)z?Tests 0-byte writes to the download stream from GetObjectMedia.rH   r   NrI   r*   )r@   r   rK   rA   r	   r!   r=   r   rL   r   rF   rM   r&   	r   r'   rN   rE   rO   rQ   rB   rD   r1   s	            r   testDownloadWithZeroWritesz0TestDaisyChainWrapper.testDownloadWithZeroWrites   sB   L	d!!4	(FC {{/0C 
D! 
  
) %%'K((6H+ 33	5
 	  !4kBX''+	k4	 M##T*o++-/C/C/EF + 
!	 # 
)	($ +* 
!	 s0   AE8E'/E>E'EE$	 E''E0c                    t        | j                  d      5 }|j                  t              }ddd       dd }|dt         }|dt        dz   }||||f|||f||||f||||f||||f||||f|||f||||||||||f
d}| j	                         }t        j                  |      D ]  \  }}	d}
|	D ]  }|
|z  }
	 | j                  |	      }t        | j                  t        |
      || j                        }| j                  ||       t        |d      5 }| j                  |j                         |
d	|z         ddd        y# 1 sw Y   xY w# 1 sw Y   xY w)
zBTests unaligned writes to the download stream from GetObjectMedia.rH   Nr   r*   rX   )z First byte first chunk unalignedzLast byte first chunk unalignedz!First byte second chunk unalignedz Last byte second chunk unalignedz First byte final chunk unalignedzLast byte final chunk unalignedzHalf chunkszMany unalignedr   rI   z0Uploaded file contents for case %s did not match)r@   r   rA   r	   r!   six	iteritemsr=   r   rL   r+   r   rF   rM   )r   rN   chunkone_bytechunk_minus_one_byte
half_chunkwrite_values_dictrO   	case_namer'   expected_contentsr6   rQ   rB   rD   s                  r   testDownloadWithPartialWritez2TestDaisyChainWrapper.testDownloadWithPartialWrite   s   	d!!4	(Fkk./e 
)
 QqzH #78q-23J +UE:,@%+OH2E:((E:E8%9:E/:"J
;z8Z!5(JJ" %%'K#&==1B#C	<%+[( &**<8h-
//

 
"55	7
 ""#6DT"m "3>J	L #" $D7 
)	(L #"s   E%EEE	c                    g }t        | j                  d      5 }	 |j                  t              }|sn|j	                  |       *	 ddd       | j                         }| j                  |      }t        | j                  | j                  || j                        }t        |d      5 }d}|j                  dt        j                         |j                  |       	 |j                  t              }|t        |      z  }|j                  dt        j                         |j                  |       |sn|j                  |       j	 ddd       | j                  |j                   d       t        |d      5 }t        | j                  d      5 }	| j                  |j                         |	j                                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)zATests seeking to the end of the wrapper (simulates getting size).rH   NrI   r?   r   whencer*   )r@   r   rA   r	   rK   r!   r=   r   rL   r   seekr   SEEK_ENDr+   r.   rM   r&   )
r   r'   rN   rE   rO   rQ   rB   rD   current_positionr1   s
             r   testSeekAndReturnz'TestDaisyChainWrapper.testSeekAndReturn   s   L	d!!4	(F{{/0
D!	  	 
) %%'K((6H+ 33	5
 
k4	 Mq5/0"''(<=CI%  2;; 7  !12
D!   
! 	X''+	k4	 M##T*o++-/C/C/EF + 
!	 5 
)	( 
!	  +* 
!	 s<   ,G(B G9G5/G)?G5GG&)G2	.G55G>c                    g }t        | j                  d      5 }	 |j                  t              }|sn|j	                  |       *	 ddd       | j                         }| j                  |      }t        | j                  | j                  || j                        }|j                  t               |j                  t               |j                  d       | j                  ||       | j                  |j                  d       t        |d      5 }t        | j                  d      5 }| j                  |j                         |j                                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   yxY w)zETests seek to non-stored position; this restarts the download thread.rH   NrI   r   rX   )r@   r   rA   r	   rK   r!   r=   r   rL   r   ro   rF   rM   r&   r_   s	            r   testRestartDownloadThreadz/TestDaisyChainWrapper.testRestartDownloadThread   sR   L	d!!4	(F{{/0
D!	  	 
) %%'K((6H+ 33	5
 1212Q  !4kBX''+	k4	 M##T*o++-/C/C/EF + 
!	 % 
)	(& +* 
!	 s/   ,E(F(/E5F(E25E>	:FF
c                 v    G d dt               }dd |d      g}| j                         }| j                  |      }t        | j                  | j
                  || j
                        }	 | j                  ||       | j                  d       y# |$ r%}| j                  dt        |             Y d}~yd}~ww xY w)	z<Tests that an exception is propagated via the upload thread.c                       e Zd Zy)LTestDaisyChainWrapper.testDownloadThreadException.<locals>.DownloadExceptionN)r8   r9   r:   r<   r   r   DownloadExceptionrw   <  s    
r   rx      a   bzDownload thread forces failurerI   Expected exceptionN)
r-   r!   r=   r   rL   r   rF   failassertInstr)r   rx   r'   rO   rQ   rB   es          r   testDownloadThreadExceptionz1TestDaisyChainWrapper.testDownloadThreadException9  s    I  	d:;L %%'K((6H+ 33	5
>
""#6D
ii$% >
mm4c!f==>s   *#B B8B33B8c                    t        | j                  | j                  | j                  g             }	 |j	                  dt
        j                         | j                  d       	 |j	                  dt
        j                         | j                  d       y# t        $ r%}| j                  dt        |             Y d}~]d}~ww xY w# t        $ r%}| j                  dt        |             Y d}~yd}~ww xY w)z8Tests that seeking fails for unsupported seek arguments.r   rm   r{   zdoes not support seek modeNr*   zInvalid seek during daisy chain)r   rL   r   r=   ro   r   SEEK_CURr|   IOErrorr}   r~   rp   )r   rB   r   s      r   testInvalidSeekz%TestDaisyChainWrapper.testInvalidSeekP  s    +DOO,0,C,C,0,E,Eb,IK:q5
ii$%?q5
ii$%  :
mm0#a&99:  ?
mm5s1v>>?s/   2B %2C	 	C!CC		C7C22C7)r8   r9   r:   r;   r    r   rL   r   r   r   	cloud_apiCloudApir=   rF   rR   rV   r]   r`   rk   rr   rt   r   r   __classcell__)r   s   @r   r   r   $   ss    3/#$89*C
 %'U__55 %'N"I2G6G>G0+LZGBG2>.?r   r   )r;   
__future__r   r   r   r   rZ   r   r   rb   gslib.cloud_apir   gslib.daisy_chain_wrapperr   gslib.storage_urlr   gslib.tests.testcaseteststestcasegslib.utils.constantsr	   r   GsUtilUnitTestCaser   r<   r   r   <module>r      sM    0 & %  '  	  
  7 2 ' ' 6
}?H77 }?r   