
    _                        S 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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rSR#                  S	 \" S
5       5       5      r " S S\R&                  5      r " S S\5      r " S S\R,                  5      r " S S\R,                  5      r " S S\R,                  5      r " S S\R,                  5      r " S S\R,                  5      r " S S\R,                  5      r " S S\5      rS rS rg)a4  Test utilities for message testing.

Includes module interface test to ensure that public parts of module are
correctly declared in __all__.

Includes message types that correspond to those defined in
services_test.proto.

Includes additional test utilities to make sure encoding/decoding libraries
conform.
    N)range)message_types)messages)utilu   русский    c              #   T   #    U  H  n[         R                  " U5      S -   v   M      g7f)    N)sixint2byte).0values     7lib/third_party/apitools/base/protorpclite/test_util.py	<genexpr>r   1   s     F:%#,,u%-:s   &(   c                   &    \ rS rSrS rS rS rSrg)TestCase4   c           	           U" U0 UD6  U R                  SUR                  -  5        g! U aN  n[        [        R                  " U[        U5      5      5      nU R                  USU< SU< S35         SnAgSnAff = f)a?  Check that exception is raised and text matches regular expression.

Args:
  exception: Exception type that is expected.
  regexp: String regular expression that is expected in error message.
  function: Callable to test.
  params: Parameters to forward to function.
  kwargs: Keyword arguments to forward to function.
z$Expected exception %s was not raisedzExpected match "z
", found ""N)fail__name__boolrematchstr
assertTrue)self	exceptionregexpfunctionparamskwargserrr   s           r   assertRaisesWithRegexpMatch$TestCase.assertRaisesWithRegexpMatch6   s}    	Nf''II<(() * 	N&#c(34EOOEHK$M N N	Ns   &) A=AA88A=c                     [         R                  " U5      u  p4[         R                  " U5      u  pVU R                  X55        U R                  XF5        g)zuCheck that two HTTP headers are the same.

Args:
  header1: Header value string 1.
  header2: header value string 2.
N)cgiparse_headerassertEqual)r   header1header2value1params1value2params2s          r   assertHeaderSameTestCase.assertHeaderSameN   sD     **73**73(*r   c                    [        U5      n[        U5      n[        5       nU(       aI  US   nUS	 [        [        U5      5       H  nXdU   :X  d  M  XG	   O   UR                  U5        U(       a  MI  / nU H  n	UR                  SU	-  5        M     U H  n	UR                  SU	-  5        M     U(       a$  U R	                  SSR                  U5      -   5        gg)zCheck two iterators or iterables are equal independent of order.

Similar to Python 2.7 assertItemsEqual.  Named differently in order to
avoid potential conflict.

Args:
  iter1: An iterator or iterable.
  iter2: An iterator or iterable.
r   z(  Item from iter1 not found in iter2: %rz(  Item from iter2 not found in iter1: %rzCollections not equivalent:

N)listr   lenappendr   join)
r   iter1iter2list1list2
unmatched1item1indexerror_messageitems
             r   assertIterEqualTestCase.assertIterEqualZ   s     UUV
!HEas5z*%L( +
 !!%( e D  :TAC  D  :TAC  II5ii./ 0 r    N)r   
__module____qualname____firstlineno__r$   r0   rA   __static_attributes__rC   r   r   r   r   4   s    N0
+"0r   r   c                   6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
ModuleInterfaceTest   ao	  Test to ensure module interface is carefully constructed.

    A module interface is the set of public objects listed in the
    module __all__ attribute. Modules that that are considered public
    should have this interface carefully declared. At all times, the
    __all__ attribute should have objects intended to be publically
    used and all other objects in the module should be considered
    unused.

    Protected attributes (those beginning with '_') and other imported
    modules should not be part of this set of variables. An exception
    is for variables that begin and end with '__' which are implicitly
    part of the interface (eg. __name__, __file__, __all__ itself,
    etc.).

    Modules that are imported in to the tested modules are an
    exception and may be left out of the __all__ definition. The test
    is done by checking the value of what would otherwise be a public
    name and not allowing it to be exported if it is an instance of a
    module. Modules that are explicitly exported are for the time
    being not permitted.

    To use this test class a module should define a new class that
    inherits first from ModuleInterfaceTest and then from
    test_util.TestCase. No other tests should be added to this test
    case, making the order of inheritance less important, but if setUp
    for some reason is overidden, it is important that
    ModuleInterfaceTest is first in the list so that its setUp method
    is invoked.

    Multiple inheritance is required so that ModuleInterfaceTest is
    not itself a test, and is not itself executed as one.

    The test class is expected to have the following class attributes
    defined:

      MODULE: A reference to the module that is being validated for interface
        correctness.

    Example:
      Module definition (hello.py):

        import sys

        __all__ = ['hello']

        def _get_outputter():
          return sys.stdout

        def hello():
          _get_outputter().write('Hello
')

      Test definition:

        import unittest
        from protorpc import test_util

        import hello

        class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
                                  test_util.TestCase):

          MODULE = hello


        class HelloTest(test_util.TestCase):
          ... Test 'hello' module ...


        if __name__ == '__main__':
          unittest.main()

    c                 v    [        U S5      (       d(  U R                  S[        U 5      R                  -  5        gg)zSet up makes sure that MODULE and IMPORTED_MODULES is defined.

This is a basic configuration test for the test itself so does not
get it's own test case.
MODULEz=You must define 'MODULE' on ModuleInterfaceTest sub-class %s.N)hasattrr   typer   r   s    r   setUpModuleInterfaceTest.setUp   s9     tX&&IIT
++,- 'r   c                     / nU R                   R                   H1  n[        U R                   U5      (       a  M   UR                  U5        M3     U(       a  U R	                  SU-  5        gg)z2Test that all attributes defined in __all__ exist.z(%s of __all__ are not defined in module.N)rL   __all__rM   r6   r   r   missing_attributes	attributes      r   testAllExist ModuleInterfaceTest.testAllExist   s\    ,,I4;;	22")))4 - II@() * r   c                 z   / n[        U R                  5       H  nUR                  S5      (       a  M  X R                  R                  ;  d  M6  [	        [        U R                  U5      [        R                  5      (       a  Mk  US:w  d  Ms  UR                  U5        M     U(       a  U R                  SU-  5        gg)z<Test that all public attributes not imported are in __all__._with_statementz.%s are not modules and not defined in __all__.N)
dirrL   
startswithrS   
isinstancegetattrtypes
ModuleTyper6   r   rT   s      r   testAllExported#ModuleInterfaceTest.testAllExported   s    T[[)I'',,[[%8%88&wt{{I'F','7'79 9!%55&--i8 * IIF() * r   c                     / nU R                   R                   H,  nUR                  S5      (       d  M  UR                  U5        M.     U(       a  U R	                  SU-  5        gg)z=Test that there are no protected variables listed in __all__.rZ   z3%s are protected variables and may not be exported.N)rL   rS   r]   r6   r   )r   protected_variablesrV   s      r    testNoExportedProtectedVariables4ModuleInterfaceTest.testNoExportedProtectedVariables   s\     ,,I##C((#**95 - IIK)* + r   c                 .   / nU R                   R                   HL  n [        U R                   U5      n[        U[        R
                  5      (       a  UR                  U5        ML  MN     U(       a  U R                  SU-  5        gg! [         a     Mz  f = f)z&Test that no modules exist in __all__.z'%s are modules and may not be exported.N)	rL   rS   r_   r^   r`   ra   r6   AttributeErrorr   )r   exported_modulesrV   r   s       r   testNoExportedModules)ModuleInterfaceTest.testNoExportedModules   s    ,,I7Y7
 eU%5%566$++I6 7 - II?&' (  " s   B
BBrC   N)r   rD   rE   rF   __doc__rP   rW   rb   rf   rk   rG   rC   r   r   rI   rI      s"    HT	-**+(r   rI   c                   :    \ rS rSrSr\R                  " SSS9rSrg)NestedMessagei  z3Simple message that gets nested in another message.   T)requiredrC   N	r   rD   rE   rF   rm   r   StringFielda_valuerG   rC   r   r   ro   ro     s    =""1t4Gr   ro   c                   b    \ rS rSrSr\R                  " \S5      r\R                  " \SSS9r	Sr
g)	HasNestedMessagei  z.Message that has another message nested in it.rp      TrepeatedrC   N)r   rD   rE   rF   rm   r   MessageFieldro   nestedrepeated_nestedrG   rC   r   r   rv   rv     s+    8""=!4F++M1tLOr   rv   c                   :    \ rS rSrSr\R                  " SSS9rSrg)
HasDefaulti  zHas a default value.rp   z	a default)defaultrC   Nrr   rC   r   r   r~   r~     s    ""1l;Gr   r~   c                      \ rS rSrSr " S S\R                  5      r\R                  " S\R                  R                  S9r\R                  " S\R                  R                  S9r\R                  " S\R                  R                  S9r\R                  " S	\R                  R"                  S9r\R                  " S
\R                  R&                  S9r\R*                  " S\R                  R,                  S9r\R0                  " S\R                  R2                  S9r\R6                  " S\R                  R8                  S9r\R<                  " \S5      rSr g)OptionalMessagei  zContains all message types.c                        \ rS rSrSrSrSrSrg)OptionalMessage.SimpleEnumi  Simple enumeration type.rp   rw   rC   Nr   rD   rE   rF   rm   VAL1VAL2rG   rC   r   r   
SimpleEnumr         &r   r   rp   )variantrw                     
   rC   N!r   rD   rE   rF   rm   r   Enumr   
FloatFieldVariantDOUBLEdouble_valueFLOATfloat_valueIntegerFieldINT64int64_valueUINT64uint64_valueINT32int32_valueBooleanFieldBOOL
bool_valuers   STRINGstring_value
BytesFieldBYTESbytes_value	EnumField
enum_valuerG   rC   r   r   r   r     s   %X]] 
 &&q(2B2B2I2IJL%%a1A1A1G1GHK''83C3C3I3IJK((H4D4D4K4KLL''83C3C3I3IJK&&q(2B2B2G2GHJ''83C3C3J3JKL%%a1A1A1G1GHK##J3Jr   r   c                      \ rS rSrSr " S S\R                  5      r\R                  " S\R                  R                  SS9r\R                  " S\R                  R                  SS9r\R                  " S	\R                  R                  SS9r\R                  " S
\R                  R"                  SS9r\R                  " S\R                  R&                  SS9r\R*                  " S\R                  R,                  SS9r\R0                  " S\R                  R2                  SS9r\R6                  " S\R                  R8                  SS9r\R<                  " \SSS9rSr g)RepeatedMessagei.  z.Contains all message types as repeated fields.c                        \ rS rSrSrSrSrSrg)RepeatedMessage.SimpleEnumi1  r   rp   rw   rC   Nr   rC   r   r   r   r   1  r   r   r   rp   T)r   ry   rw   r   r   r   r   r   r   r   rx   rC   Nr   rC   r   r   r   r   .  s_   8X]] 
 &&q/7/?/?/F/F046L %%a.6.>.>.D.D/35K ''080@0@0F0F157K ((191A1A1H1H268L ''080@0@0F0F157K &&q/7/?/?/D/D046J ''080@0@0G0G157L %%a.6.>.>.D.D/35K ##J$&-13Jr   r   c                   ^    \ rS rSr\R
                  " \S5      r\R
                  " \SSS9rSr	g)HasOptionalNestedMessageiS  rp   rw   Trx   rC   N)
r   rD   rE   rF   r   rz   r   r{   r|   rG   rC   r   r   r   r   S  s(    ""?A6F++OQNOr   r   c                       \ rS rSrSrSrS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rSrg)ProtoConformanceTestBaseiZ  u	  Protocol conformance test base class.

Each supported protocol should implement two methods that support encoding
and decoding of Message objects in that format:

  encode_message(message) - Serialize to encoding.
  encode_message(message, encoded_message) - Deserialize from encoding.

Tests for the modules where these functions are implemented should extend
this class in order to support basic behavioral expectations.  This ensures
that protocols correctly encode and decode message transparently to the
caller.

In order to support these test, the base class should also extend
the TestCase class and implement the following class attributes
which define the encoded version of certain protocol buffers:

  encoded_partial:
    <OptionalMessage
      double_value: 1.23
      int64_value: -100000000000
      string_value: u"a string"
      enum_value: OptionalMessage.SimpleEnum.VAL2
      >

  encoded_full:
    <OptionalMessage
      double_value: 1.23
      float_value: -2.5
      int64_value: -100000000000
      uint64_value: 102020202020
      int32_value: 1020
      bool_value: true
      string_value: u"a stringя"
      bytes_value: b"a bytesÿþ"
      enum_value: OptionalMessage.SimpleEnum.VAL2
      >

  encoded_repeated:
    <RepeatedMessage
      double_value: [1.23, 2.3]
      float_value: [-2.5, 0.5]
      int64_value: [-100000000000, 20]
      uint64_value: [102020202020, 10]
      int32_value: [1020, 718]
      bool_value: [true, false]
      string_value: [u"a stringя", u"another string"]
      bytes_value: [b"a bytesÿþ", b"another bytes"]
      enum_value: [OptionalMessage.SimpleEnum.VAL2,
                   OptionalMessage.SimpleEnum.VAL 1]
      >

  encoded_nested:
    <HasNestedMessage
      nested: <NestedMessage
        a_value: "a string"
        >
      >

  encoded_repeated_nested:
    <HasNestedMessage
      repeated_nested: [
          <NestedMessage a_value: "a string">,
          <NestedMessage a_value: "another string">
        ]
      >

  unexpected_tag_message:
    An encoded message that has an undefined tag or number in the stream.

  encoded_default_assigned:
    <HasDefault
      a_value: "a default"
      >

  encoded_nested_empty:
    <HasOptionalNestedMessage
      nested: <OptionalMessage>
      >

  encoded_invalid_enum:
    <OptionalMessage
      enum_value: (invalid value for serialization type)
      >

  encoded_invalid_repeated_enum:
    <RepeatedMessage
      enum_value: (invalid value for serialization type)
      >
 c                     [        5       nU R                  [        R                  U R                  R
                  U5        g N)ro   assertRaisesr   ValidationErrorPROTOLIBencode_messager   messages     r   testEncodeInvalidMessage1ProtoConformanceTestBase.testEncodeInvalidMessage  s/    /(22--66	Ar   c                 &    U R                  X5        g)a   Compare two encoded protocol values.

Can be overridden by sub-classes to special case comparison.
For example, to eliminate white space from output that is not
relevant to encoding.

Args:
  expected_encoded: Expected string encoded value.
  actual_encoded: Actual string encoded value.
N)r)   )r   expected_encodedactual_encodeds      r   CompareEncoded'ProtoConformanceTestBase.CompareEncoded  s     	):r   c                     U R                   R                  [        U5      U5      nU R                  X#5        U R	                  XR                   R                  U5      5        g r   )r   decode_messagerN   r)   r   r   )r   encodedexpected_messager   s       r   EncodeDecode%ProtoConformanceTestBase.EncodeDecode  sJ    --..t4D/EwO)3G]]%A%A'%JKr   c                 L    U R                  U R                  [        5       5        g r   )r   encoded_empty_messager   rO   s    r   testEmptyMessage)ProtoConformanceTestBase.testEmptyMessage  s    $44o6GHr   c                     [        5       nSUl        SUl        SUl        SUl        [         R
                  R                  Ul        U R                  U R                  U5        g)z#Test message with a few values set.Gz? h]   a stringN)
r   r   r   r   r   r   r   r   r   encoded_partialr   s     r   testPartial$ProtoConformanceTestBase.testPartial  sT    !##+"*,77<<$..8r   c                     [        5       nSUl        SUl        SUl        SUl        SUl        SUl        SUl        SUl        [         R                  R                  Ul        U R                  U R                  U5        g	)
zTest all types.r         r      $>_ r   T
   a stringя	   a bytesN)r   r   r   r   r   r   r   r   r   r   r   r   r   encoded_fullr   s     r   testFull!ProtoConformanceTestBase.testFull  st    !##"++"!00,77<<$++W5r   c                 R   [        5       nSS/Ul        SS/Ul        SS/Ul        SS/Ul        S	S
/Ul        SS/Ul        SS/Ul        SS/Ul        [         R                  R                  [         R                  R                  /Ul        U R                  U R                  U5        g)zTest repeated fields.r   gffffff@r   g      ?r      r   r   r   i  TFr   another stringr   s   another bytesN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   encoded_repeatedr   s     r   testRepeated%ProtoConformanceTestBase.testRepeated  s    !# $c{#Sk,b1 ,b1#Sk"E] 13DE13CD-88==-88==? 	$//9r   c                 ~    [        5       nSUl        [        5       nXl        U R	                  U R
                  U5        g)zTest nested messages.r   N)ro   rt   rv   r{   r   encoded_nested)r   nested_messager   s      r   
testNested#ProtoConformanceTestBase.testNested  s4    &!,"$'$--w7r   c                     [        5       nSUl        [        5       nSUl        [        5       nX/Ul        U R	                  U R
                  U5        g)zTest repeated nested messages.r   r   N)ro   rt   rv   r|   r   encoded_repeated_nested)r   nested_message1nested_message2r   s       r   testRepeatedNested+ProtoConformanceTestBase.testRepeatedNested  sI    '/"-'/"3"$#2"D$66@r   c                 ^    [        5       nSUl        U R                  U R                  U5        g)z,Test that encoding str on StringField works.LatinN)r   r   r   encoded_string_typesr   s     r   testStringTypes(ProtoConformanceTestBase.testStringTypes  s(    !#&$33W=r   c                     [        5       nU R                  [        R                  SU R                  R
                  U5        g)z.Test that cannot encode uninitialized message.z7Message NestedMessage is missing required field a_valueN)ro   r$   r   r   r   r   )r   rq   s     r   testEncodeUninitialized0ProtoConformanceTestBase.testEncodeUninitialized  s5     ?(()A)A*B)-)E)E)1		3r   c                     U R                   R                  [        U R                  5      nU R	                  [        5       U5        U R	                  U R                  U R                   R                  U5      5        g)z-Test decoding and encoding unexpected fields.N)r   r   r   unexpected_tag_messager)   r   )r   loaded_messages     r   testUnexpectedField,ProtoConformanceTestBase.testUnexpectedField!  sa    55T88: 	*N; 	44--66~F	Hr   c                 L    U R                  U R                  [        5       5        g)z7Test that default is not sent when nothing is assigned.N)r   r   r~   rO   s    r   testDoNotSendDefault-ProtoConformanceTestBase.testDoNotSendDefault-  s    $44jlCr   c                     [        5       n[         R                  R                  Ul        U R                  U R                  U5        g)z2Test that default is sent when explcitly assigned.N)r~   rt   r   r   encoded_default_assignedr   s     r   !testSendDefaultExplicitlyAssigned:ProtoConformanceTestBase.testSendDefaultExplicitlyAssigned1  s2    ,$,,44$77Ar   c                 n    [        5       n[        5       Ul        U R                  U R                  U5        gz%Test encoding a nested empty message.N)r   r   r{   r   encoded_nested_emptyr   s     r   testEncodingNestedEmptyMessage7ProtoConformanceTestBase.testEncodingNestedEmptyMessage9  s*    *,(*$33W=r   c                     [        5       n[        5       [        5       /Ul        U R                  U R                  U5        gr  )r   r   r|   r   encoded_repeated_nested_emptyr   s     r   &testEncodingRepeatedNestedEmptyMessage?ProtoConformanceTestBase.testEncodingRepeatedNestedEmptyMessage@  s3    *,#2#4o6G"H$<<gFr   c                 j    U R                  [        U R                  R                  [        5      5        g r   )r   r^   r   CONTENT_TYPEr   rO   s    r   testContentType(ProtoConformanceTestBase.testContentTypeG  s    
4==#=#=sCDr   c                     U R                   R                  [        U R                  5      n[        5       nU R	                  X!5        U R                   R                  U5      nU R	                  U R                  U5        g r   )r   r   r   encoded_invalid_enumr)   r   r   decodedr   r   s       r   testDecodeInvalidEnumType2ProtoConformanceTestBase.testDecodeInvalidEnumTypeJ  sd    
 --../3/H/HJ!#*--..w722G<r   c                 <   U R                   R                  [        U R                  5      n[        5       n[        R                  R
                  /Ul        U R                  X!5        U R                   R                  U5      nU R                  U R                  U5        g r   )	r   r   r   encoded_invalid_repeated_enumr   r   r   r)   r   r  s       r   !testDecodeInvalidRepeatedEnumType:ProtoConformanceTestBase.testDecodeInvalidRepeatedEnumTypeV  s{    
 --../3/Q/QS!#-88==>*--..w7;;WEr   c           	          " S S[         R                  5      n[        R                  " SSSSSSS	5      nU" US
9nU R                  R	                  XR                  R                  U5      5      nU R                  UR                  U5        g)z7Test that DateTimeFields are encoded/decoded correctly.c                   8    \ rS rSr\R
                  " S5      rSrg)BProtoConformanceTestBase.testDateTimeNoTimeZone.<locals>.MyMessageif  rp   rC   Nr   rD   rE   rF   r   DateTimeFieldr   rG   rC   r   r   	MyMessager  f      !//2Er   r    rp   r      $      x r   N)r   Messagedatetimer   r   r   r)   r   r   r  r   r   r  s        r   testDateTimeNoTimeZone/ProtoConformanceTestBase.testDateTimeNoTimeZonec  sv    	3(( 	3 !!$1b"b&A%(--..}}33G<>.r   c                 D    " S S[         R                  5      n[        R                  " SSSSSSS	[        R                  " S
5      5      nU" US9nU R
                  R                  XR
                  R                  U5      5      nU R                  UR                  U5        g)z$Test DateTimeFields with time zones.c                   8    \ rS rSr\R
                  " S5      rSrg)DProtoConformanceTestBase.testDateTimeWithTimeZone.<locals>.MyMessageir  rp   rC   Nr  rC   r   r   r  r-  r  r  r   r  r   rp   r   r!  r"  r#  r$  i  r%  N)
r   r&  r'  r   TimeZoneOffsetr   r   r   r)   r   r(  s        r   testDateTimeWithTimeZone1ProtoConformanceTestBase.testDateTimeWithTimeZoneo  s    	3(( 	3 !!$1b"b&"&"5"5f"=?%(--..}}33G<>.r   rC   N)r   rD   rE   rF   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r)  r/  rG   rC   r   r   r   r   Z  s    Yv A
;L
I	96: 8
A>3
HDB>GE
=F
//r   r   c                      [         R                   " [         R                  [         R                  5      n  U R                  S5        U R	                  5       S   nU R                  5         U$ ! U R                  5         f = f)zFind an unused port to use in tests.

Derived from Damon Kohlers example:

  http://code.activestate.com/recipes/531822-pick-unused-port
)	localhostr   rp   )socketAF_INETSOCK_STREAMbindgetsocknameclose)tempports     r   pick_unused_portr;  }  s^     ==););<D		"#!!$

K 	

s   $A+ +A=c                     U R                   S:X  aI  [        R                  " U 5      n[        R                  R                  U5      R                  S5      S   nU$ U R                   $ )zGet the module name.

Args:
  module_attribute: An attribute of the module.

Returns:
  The fully qualified module name or simple module name where
  'module_attribute' is defined if the module name is "__main__".
__main__.r   )rD   inspectgetfileospathbasenamesplit)module_attributemodule_filer   s      r   get_module_namerG    sV     ""j0oo&67''"";/55c:1=&&&r   ) rm   r'   r'  r?  rA  r   r3  r`   unittestr
   	six.movesr   apitools.base.protorpcliter   r   r   RUSSIANr7   BINARYr   objectrI   r&  ro   rv   r~   r   r   r   r   r;  rG  rC   r   r   <module>rN     s  $
    	 	    
  4 / + 8 
F5:F	FH0x   H0VF(& F(R5H$$ 5Mx'' M<!! <4h&& 4&"3h&& "3JOx// O`/v `/F	 'r   