Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

testGatewayAddresses.py 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # The purpose of this test is to ensure that the gateways objects
  2. # do the right thing WRT COM rules about object identity etc.
  3. # Also includes a basic test that we support inheritance correctly in
  4. # gateway interfaces.
  5. # For our test, we create an object of type IID_IPersistStorage
  6. # This interface derives from IPersist.
  7. # Therefore, QI's for IID_IDispatch, IID_IUnknown, IID_IPersist and
  8. # IID_IPersistStorage should all return the same gateway object.
  9. #
  10. # In addition, the interface should only need to declare itself as
  11. # using the IPersistStorage interface, and as the gateway derives
  12. # from IPersist, it should automatically be available without declaration.
  13. #
  14. # We also create an object of type IID_I??, and perform a QI for it.
  15. # We then jump through a number of hoops, ensuring that the objects
  16. # returned by the QIs follow all the rules.
  17. #
  18. # Here is Gregs summary of the rules:
  19. # 1) the set of supported interfaces is static and unchanging
  20. # 2) symmetric: if you QI an interface for that interface, it succeeds
  21. # 3) reflexive: if you QI against A for B, the new pointer must succeed
  22. # for a QI for A
  23. # 4) transitive: if you QI for B, then QI that for C, then QI'ing A for C
  24. # must succeed
  25. #
  26. #
  27. # Note that 1) Requires cooperation of the Python programmer. The rule to keep is:
  28. # "whenever you return an _object_ from _query_interface_(), you must return the
  29. # same object each time for a given IID. Note that you must return the same
  30. # _wrapped_ object
  31. # you
  32. # The rest are tested here.
  33. import pythoncom
  34. from win32com.server.util import wrap
  35. from .util import CheckClean
  36. numErrors = 0
  37. # Check that the 2 objects both have identical COM pointers.
  38. def CheckSameCOMObject(ob1, ob2):
  39. addr1 = repr(ob1).split()[6][:-1]
  40. addr2 = repr(ob2).split()[6][:-1]
  41. return addr1 == addr2
  42. # Check that the objects conform to COM identity rules.
  43. def CheckObjectIdentity(ob1, ob2):
  44. u1 = ob1.QueryInterface(pythoncom.IID_IUnknown)
  45. u2 = ob2.QueryInterface(pythoncom.IID_IUnknown)
  46. return CheckSameCOMObject(u1, u2)
  47. def FailObjectIdentity(ob1, ob2, when):
  48. if not CheckObjectIdentity(ob1, ob2):
  49. global numErrors
  50. numErrors = numErrors + 1
  51. print(when, "are not identical (%s, %s)" % (repr(ob1), repr(ob2)))
  52. class Dummy:
  53. _public_methods_ = [] # We never attempt to make a call on this object.
  54. _com_interfaces_ = [pythoncom.IID_IPersistStorage]
  55. class Dummy2:
  56. _public_methods_ = [] # We never attempt to make a call on this object.
  57. _com_interfaces_ = [
  58. pythoncom.IID_IPersistStorage,
  59. pythoncom.IID_IExternalConnection,
  60. ]
  61. class DeletgatedDummy:
  62. _public_methods_ = []
  63. class Dummy3:
  64. _public_methods_ = [] # We never attempt to make a call on this object.
  65. _com_interfaces_ = [pythoncom.IID_IPersistStorage]
  66. def _query_interface_(self, iid):
  67. if iid == pythoncom.IID_IExternalConnection:
  68. # This will NEVER work - can only wrap the object once!
  69. return wrap(DelegatedDummy())
  70. def TestGatewayInheritance():
  71. # By default, wrap() creates and discards a temporary object.
  72. # This is not necessary, but just the current implementation of wrap.
  73. # As the object is correctly discarded, it doesnt affect this test.
  74. o = wrap(Dummy(), pythoncom.IID_IPersistStorage)
  75. o2 = o.QueryInterface(pythoncom.IID_IUnknown)
  76. FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IUnknown")
  77. o3 = o2.QueryInterface(pythoncom.IID_IDispatch)
  78. FailObjectIdentity(o2, o3, "IID_IUnknown->IID_IDispatch")
  79. FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IDispatch")
  80. o4 = o3.QueryInterface(pythoncom.IID_IPersistStorage)
  81. FailObjectIdentity(o, o4, "IID_IPersistStorage->IID_IPersistStorage(2)")
  82. FailObjectIdentity(o2, o4, "IID_IUnknown->IID_IPersistStorage(2)")
  83. FailObjectIdentity(o3, o4, "IID_IDispatch->IID_IPersistStorage(2)")
  84. o5 = o4.QueryInterface(pythoncom.IID_IPersist)
  85. FailObjectIdentity(o, o5, "IID_IPersistStorage->IID_IPersist")
  86. FailObjectIdentity(o2, o5, "IID_IUnknown->IID_IPersist")
  87. FailObjectIdentity(o3, o5, "IID_IDispatch->IID_IPersist")
  88. FailObjectIdentity(o4, o5, "IID_IPersistStorage(2)->IID_IPersist")
  89. def TestMultiInterface():
  90. o = wrap(Dummy2(), pythoncom.IID_IPersistStorage)
  91. o2 = o.QueryInterface(pythoncom.IID_IExternalConnection)
  92. FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IExternalConnection")
  93. # Make the same QI again, to make sure it is stable.
  94. o22 = o.QueryInterface(pythoncom.IID_IExternalConnection)
  95. FailObjectIdentity(o, o22, "IID_IPersistStorage->IID_IExternalConnection")
  96. FailObjectIdentity(
  97. o2, o22, "IID_IPersistStorage->IID_IExternalConnection (stability)"
  98. )
  99. o3 = o2.QueryInterface(pythoncom.IID_IPersistStorage)
  100. FailObjectIdentity(o2, o3, "IID_IExternalConnection->IID_IPersistStorage")
  101. FailObjectIdentity(
  102. o, o3, "IID_IPersistStorage->IID_IExternalConnection->IID_IPersistStorage"
  103. )
  104. def test():
  105. TestGatewayInheritance()
  106. TestMultiInterface()
  107. if numErrors == 0:
  108. print("Worked ok")
  109. else:
  110. print("There were", numErrors, "errors.")
  111. if __name__ == "__main__":
  112. test()
  113. CheckClean()