0001 # The purpose of this test is to ensure that the gateways objects 0002 # do the right thing WRT COM rules about object identity etc. 0003 0004 # Also includes a basic test that we support inheritance correctly in 0005 # gateway interfaces. 0006 0007 # For our test, we create an object of type IID_IPersistStorage 0008 # This interface derives from IPersist. 0009 # Therefore, QI's for IID_IDispatch, IID_IUnknown, IID_IPersist and 0010 # IID_IPersistStorage should all return the same gateway object. 0011 # 0012 # In addition, the interface should only need to declare itself as 0013 # using the IPersistStorage interface, and as the gateway derives 0014 # from IPersist, it should automatically be available without declaration. 0015 # 0016 # We also create an object of type IID_I??, and perform a QI for it. 0017 # We then jump through a number of hoops, ensuring that the objects 0018 # returned by the QIs follow all the rules. 0019 # 0020 # Here is Gregs summary of the rules: 0021 # 1) the set of supported interfaces is static and unchanging 0022 # 2) symmetric: if you QI an interface for that interface, it succeeds 0023 # 3) reflexive: if you QI against A for B, the new pointer must succeed 0024 # for a QI for A 0025 # 4) transitive: if you QI for B, then QI that for C, then QI’ing A for C 0026 # must succeed 0027 # 0028 # 0029 # Note that 1) Requires cooperation of the Python programmer. The rule to keep is: 0030 # "whenever you return an _object_ from _query_interface_(), you must return the 0031 # same object each time for a given IID. Note that you must return the same 0032 # _wrapped_ object 0033 # you 0034 # The rest are tested here. 0035 0036 0037 from win32com.server.util import wrap 0038 import pythoncom 0039 import string 0040 from util import CheckClean 0041 0042 numErrors = 0 0043 0044 # Check that the 2 objects both have identical COM pointers. 0045 def CheckSameCOMObject(ob1, ob2): 0046 addr1 = string.split(repr(ob1))[6][:-1] 0047 addr2 = string.split(repr(ob2))[6][:-1] 0048 return addr1==addr2 0049 0050 # Check that the objects conform to COM identity rules. 0051 def CheckObjectIdentity(ob1, ob2): 0052 u1 = ob1.QueryInterface(pythoncom.IID_IUnknown) 0053 u2 = ob2.QueryInterface(pythoncom.IID_IUnknown) 0054 return CheckSameCOMObject(u1, u2) 0055 0056 def FailObjectIdentity(ob1, ob2, when): 0057 if not CheckObjectIdentity(ob1, ob2): 0058 global numErrors 0059 numErrors = numErrors + 1 0060 print when, "are not identical (%s, %s)" % (`ob1`, `ob2`) 0061 0062 0063 class Dummy: 0064 _public_methods_ = [] # We never attempt to make a call on this object. 0065 _com_interfaces_ = [pythoncom.IID_IPersistStorage] 0066 0067 class Dummy2: 0068 _public_methods_ = [] # We never attempt to make a call on this object. 0069 _com_interfaces_ = [pythoncom.IID_IPersistStorage, pythoncom.IID_IExternalConnection] 0070 0071 class DeletgatedDummy: 0072 _public_methods_ = [] 0073 0074 class Dummy3: 0075 _public_methods_ = [] # We never attempt to make a call on this object. 0076 _com_interfaces_ = [pythoncom.IID_IPersistStorage] 0077 def _query_interface_(self, iid): 0078 if iid==pythoncom.IID_IExternalConnection: 0079 # This will NEVER work - can only wrap the object once! 0080 return wrap(DelegatedDummy()) 0081 0082 def TestGatewayInheritance(): 0083 # By default, wrap() creates and discards a temporary object. 0084 # This is not necessary, but just the current implementation of wrap. 0085 # As the object is correctly discarded, it doesnt affect this test. 0086 o = wrap(Dummy(), pythoncom.IID_IPersistStorage) 0087 o2 = o.QueryInterface(pythoncom.IID_IUnknown) 0088 FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IUnknown") 0089 0090 o3 = o2.QueryInterface(pythoncom.IID_IDispatch) 0091 0092 FailObjectIdentity(o2, o3, "IID_IUnknown->IID_IDispatch") 0093 FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IDispatch") 0094 0095 o4 = o3.QueryInterface(pythoncom.IID_IPersistStorage) 0096 FailObjectIdentity(o, o4, "IID_IPersistStorage->IID_IPersistStorage(2)") 0097 FailObjectIdentity(o2, o4, "IID_IUnknown->IID_IPersistStorage(2)") 0098 FailObjectIdentity(o3, o4, "IID_IDispatch->IID_IPersistStorage(2)") 0099 0100 0101 o5 = o4.QueryInterface(pythoncom.IID_IPersist) 0102 FailObjectIdentity(o, o5, "IID_IPersistStorage->IID_IPersist") 0103 FailObjectIdentity(o2, o5, "IID_IUnknown->IID_IPersist") 0104 FailObjectIdentity(o3, o5, "IID_IDispatch->IID_IPersist") 0105 FailObjectIdentity(o4, o5, "IID_IPersistStorage(2)->IID_IPersist") 0106 0107 def TestMultiInterface(): 0108 o = wrap(Dummy2(), pythoncom.IID_IPersistStorage) 0109 o2 = o.QueryInterface(pythoncom.IID_IExternalConnection) 0110 0111 FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IExternalConnection") 0112 0113 # Make the same QI again, to make sure it is stable. 0114 o22 = o.QueryInterface(pythoncom.IID_IExternalConnection) 0115 FailObjectIdentity(o, o22, "IID_IPersistStorage->IID_IExternalConnection") 0116 FailObjectIdentity(o2, o22, "IID_IPersistStorage->IID_IExternalConnection (stability)") 0117 0118 o3 = o2.QueryInterface(pythoncom.IID_IPersistStorage) 0119 FailObjectIdentity(o2, o3, "IID_IExternalConnection->IID_IPersistStorage") 0120 FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IExternalConnection->IID_IPersistStorage") 0121 0122 0123 def test(): 0124 TestGatewayInheritance() 0125 TestMultiInterface() 0126 if numErrors==0: 0127 print "Worked ok" 0128 else: 0129 print "There were", numErrors, "errors." 0130 0131 0132 if __name__=='__main__': 0133 test() 0134 CheckClean() 0135
Generated by PyXR 0.9.4