0001 # NOTE - Still seems to be a leak here somewhere 0002 # gateway count doesnt hit zero. Hence the print statements! 0003 0004 import sys; sys.coinit_flags=0 # Must be free-threaded! 0005 import win32api, types, pythoncom, time 0006 import sys, os, win32com, win32com.client.connect 0007 from win32com.test.util import CheckClean 0008 from win32com.client import constants 0009 import win32com 0010 from util import RegisterPythonServer 0011 0012 importMsg = "**** PyCOMTest is not installed ***\n PyCOMTest is a Python test specific COM client and server.\n It is likely this server is not installed on this machine\n To install the server, you must get the win32com sources\n and build it using MS Visual C++" 0013 0014 error = "testPyCOMTest error" 0015 0016 # This test uses a Python implemented COM server - ensure correctly registered. 0017 RegisterPythonServer(os.path.join(win32com.__path__[0], "servers", "test_pycomtest.py")) 0018 0019 from win32com.client import gencache 0020 try: 0021 gencache.EnsureModule('{6BCDCB60-5605-11D0-AE5F-CADD4C000000}', 0, 1, 1) 0022 except pythoncom.com_error: 0023 print "The PyCOMTest module can not be located or generated." 0024 print importMsg 0025 raise RuntimeError, importMsg 0026 0027 # We had a bg where RegisterInterfaces would fail if gencache had 0028 # already been run - exercise that here 0029 from win32com import universal 0030 universal.RegisterInterfaces('{6BCDCB60-5605-11D0-AE5F-CADD4C000000}', 0, 1, 1) 0031 0032 verbose = 0 0033 0034 def progress(*args): 0035 if verbose: 0036 for arg in args: 0037 print arg, 0038 print 0039 0040 def TestApplyResult(fn, args, result): 0041 try: 0042 import string 0043 fnName = string.split(str(fn))[1] 0044 except: 0045 fnName = str(fn) 0046 progress("Testing ", fnName) 0047 pref = "function " + fnName 0048 try: 0049 rc = apply(fn, args) 0050 if rc != result: 0051 raise error, "%s failed - result not %d but %d" % (pref, result, rc) 0052 except: 0053 t, v, tb = sys.exc_info() 0054 tb = None 0055 raise error, "%s caused exception %s,%s" % (pref, t, v) 0056 0057 # Simple handler class. This demo only fires one event. 0058 class RandomEventHandler: 0059 def _Init(self): 0060 self.fireds = {} 0061 def OnFire(self, no): 0062 try: 0063 self.fireds[no] = self.fireds[no] + 1 0064 except KeyError: 0065 self.fireds[no] = 0 0066 def _DumpFireds(self): 0067 if not self.fireds: 0068 print "ERROR: Nothing was recieved!" 0069 for firedId, no in self.fireds.items(): 0070 progress("ID %d fired %d times" % (firedId, no)) 0071 0072 def TestDynamic(): 0073 progress("Testing Dynamic") 0074 import win32com.client.dynamic 0075 o = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest") 0076 0077 progress("Getting counter") 0078 counter = o.GetSimpleCounter() 0079 TestCounter(counter, 0) 0080 0081 progress("Checking default args") 0082 rc = o.TestOptionals() 0083 if rc[:-1] != ("def", 0, 1) or abs(rc[-1]-3.14)>.01: 0084 print rc 0085 raise error, "Did not get the optional values correctly" 0086 rc = o.TestOptionals("Hi", 2, 3, 1.1) 0087 if rc[:-1] != ("Hi", 2, 3) or abs(rc[-1]-1.1)>.01: 0088 print rc 0089 raise error, "Did not get the specified optional values correctly" 0090 rc = o.TestOptionals2(0) 0091 if rc != (0, "", 1): 0092 print rc 0093 raise error, "Did not get the optional2 values correctly" 0094 rc = o.TestOptionals2(1.1, "Hi", 2) 0095 if rc[1:] != ("Hi", 2) or abs(rc[0]-1.1)>.01: 0096 print rc 0097 raise error, "Did not get the specified optional2 values correctly" 0098 0099 # if verbose: print "Testing structs" 0100 r = o.GetStruct() 0101 assert r.int_value == 99 and str(r.str_value)=="Hello from C++" 0102 counter = win32com.client.dynamic.DumbDispatch("PyCOMTest.SimpleCounter") 0103 TestCounter(counter, 0) 0104 assert o.DoubleString("foo") == "foofoo" 0105 0106 l=[] 0107 TestApplyResult(o.SetVariantSafeArray, (l,), len(l)) 0108 l=[1,2,3,4] 0109 TestApplyResult(o.SetVariantSafeArray, (l,), len(l)) 0110 # TestApplyResult(o.SetIntSafeArray, (l,), len(l)) Still fails, and probably always will. 0111 TestApplyResult(o.CheckVariantSafeArray, ((1,2,3,4,),), 1) 0112 o.LongProp = 3 0113 if o.LongProp != 3 or o.IntProp != 3: 0114 raise error, "Property value wrong - got %d/%d" % (o.LongProp,o.IntProp) 0115 0116 def TestGenerated(): 0117 # Create an instance of the server. 0118 from win32com.client.gencache import EnsureDispatch 0119 o = EnsureDispatch("PyCOMTest.PyCOMTest") 0120 counter = o.GetSimpleCounter() 0121 TestCounter(counter, 1) 0122 0123 counter = EnsureDispatch("PyCOMTest.SimpleCounter") 0124 TestCounter(counter, 1) 0125 0126 i1, i2 = o.GetMultipleInterfaces() 0127 if type(i1) != types.InstanceType or type(i2) != types.InstanceType: 0128 # Yay - is now an instance returned! 0129 raise error, "GetMultipleInterfaces did not return instances - got '%s', '%s'" % (i1, i2) 0130 del i1 0131 del i2 0132 0133 progress("Checking default args") 0134 rc = o.TestOptionals() 0135 if rc[:-1] != ("def", 0, 1) or abs(rc[-1]-3.14)>.01: 0136 print rc 0137 raise error, "Did not get the optional values correctly" 0138 rc = o.TestOptionals("Hi", 2, 3, 1.1) 0139 if rc[:-1] != ("Hi", 2, 3) or abs(rc[-1]-1.1)>.01: 0140 print rc 0141 raise error, "Did not get the specified optional values correctly" 0142 rc = o.TestOptionals2(0) 0143 if rc != (0, "", 1): 0144 print rc 0145 raise error, "Did not get the optional2 values correctly" 0146 rc = o.TestOptionals2(1.1, "Hi", 2) 0147 if rc[1:] != ("Hi", 2) or abs(rc[0]-1.1)>.01: 0148 print rc 0149 raise error, "Did not get the specified optional2 values correctly" 0150 0151 progress("Checking var args") 0152 o.SetVarArgs("Hi", "There", "From", "Python", 1) 0153 if o.GetLastVarArgs() != ("Hi", "There", "From", "Python", 1): 0154 raise error, "VarArgs failed -" + str(o.GetLastVarArgs()) 0155 progress("Checking getting/passing IUnknown") 0156 if o.GetSetUnknown(o) != o: 0157 raise error, "GetSetUnknown failed" 0158 progress("Checking getting/passing IDispatch") 0159 if type(o.GetSetDispatch(o)) !=types.InstanceType: 0160 raise error, "GetSetDispatch failed" 0161 progress("Checking getting/passing IDispatch of known type") 0162 if o.GetSetInterface(o).__class__ != o.__class__: 0163 raise error, "GetSetDispatch failed" 0164 0165 # Pass some non-sequence objects to our array decoder, and watch it fail. 0166 try: 0167 o.SetVariantSafeArray("foo") 0168 raise error, "Expected a type error" 0169 except TypeError: 0170 pass 0171 try: 0172 o.SetVariantSafeArray(666) 0173 raise error, "Expected a type error" 0174 except TypeError: 0175 pass 0176 0177 o.GetSimpleSafeArray(None) 0178 TestApplyResult(o.GetSimpleSafeArray, (None,), tuple(range(10))) 0179 resultCheck = tuple(range(5)), tuple(range(10)), tuple(range(20)) 0180 TestApplyResult(o.GetSafeArrays, (None, None, None), resultCheck) 0181 0182 l=[1,2,3,4] 0183 TestApplyResult(o.SetVariantSafeArray, (l,), len(l)) 0184 TestApplyResult(o.SetIntSafeArray, (l,), len(l)) 0185 l=[] 0186 TestApplyResult(o.SetVariantSafeArray, (l,), len(l)) 0187 TestApplyResult(o.SetIntSafeArray, (l,), len(l)) 0188 # Tell the server to do what it does! 0189 TestApplyResult(o.Test, ("Unused", 99), 1) # A bool function 0190 TestApplyResult(o.Test, ("Unused", -1), 1) # A bool function 0191 TestApplyResult(o.Test, ("Unused", 1==1), 1) # A bool function 0192 TestApplyResult(o.Test, ("Unused", 0), 0) 0193 TestApplyResult(o.Test, ("Unused", 1==0), 0) 0194 TestApplyResult(o.Test2, (constants.Attr2,), constants.Attr2) 0195 TestApplyResult(o.Test3, (constants.Attr2,), constants.Attr2) 0196 TestApplyResult(o.Test4, (constants.Attr2,), constants.Attr2) 0197 TestApplyResult(o.Test5, (constants.Attr2,), constants.Attr2) 0198 0199 now = pythoncom.MakeTime(time.gmtime(time.time())) 0200 later = pythoncom.MakeTime(time.gmtime(time.time()+1)) 0201 TestApplyResult(o.EarliestDate, (now, later), now) 0202 0203 assert o.DoubleString("foo") == "foofoo" 0204 assert o.DoubleInOutString("foo") == "foofoo" 0205 0206 o.LongProp = 3 0207 if o.LongProp != 3 or o.IntProp != 3: 0208 raise error, "Property value wrong - got %d/%d" % (o.LongProp,o.IntProp) 0209 0210 # Do the connection point thing... 0211 # Create a connection object. 0212 progress("Testing connection points") 0213 sessions = [] 0214 o = win32com.client.DispatchWithEvents( o, RandomEventHandler) 0215 o._Init() 0216 0217 try: 0218 for i in range(3): 0219 session = o.Start() 0220 sessions.append(session) 0221 time.sleep(.5) 0222 finally: 0223 # Stop the servers 0224 for session in sessions: 0225 o.Stop(session) 0226 o._DumpFireds() 0227 progress("Finished generated .py test.") 0228 0229 def TestCounter(counter, bIsGenerated): 0230 # Test random access into container 0231 progress("Testing counter", `counter`) 0232 import random 0233 for i in xrange(50): 0234 num = int(random.random() * len(counter)) 0235 try: 0236 ret = counter[num] 0237 if ret != num+1: 0238 raise error, "Random access into element %d failed - return was %s" % (num,`ret`) 0239 except IndexError: 0240 raise error, "** IndexError accessing collection element %d" % num 0241 0242 num = 0 0243 if bIsGenerated: 0244 counter.SetTestProperty(1) 0245 counter.TestProperty = 1 # Note this has a second, default arg. 0246 counter.SetTestProperty(1,2) 0247 if counter.TestPropertyWithDef != 0: 0248 raise error, "Unexpected property set value!" 0249 if counter.TestPropertyNoDef(1) != 1: 0250 raise error, "Unexpected property set value!" 0251 else: 0252 pass 0253 # counter.TestProperty = 1 0254 0255 counter.LBound=1 0256 counter.UBound=10 0257 if counter.LBound <> 1 or counter.UBound<>10: 0258 print "** Error - counter did not keep its properties" 0259 0260 if bIsGenerated: 0261 bounds = counter.GetBounds() 0262 if bounds[0]<>1 or bounds[1]<>10: 0263 raise error, "** Error - counter did not give the same properties back" 0264 counter.SetBounds(bounds[0], bounds[1]) 0265 0266 for item in counter: 0267 num = num + 1 0268 if num <> len(counter): 0269 raise error, "*** Length of counter and loop iterations dont match ***" 0270 if num <> 10: 0271 raise error, "*** Unexpected number of loop iterations ***" 0272 0273 counter = counter._enum_.Clone() # Test Clone() and enum directly 0274 counter.Reset() 0275 num = 0 0276 for item in counter: 0277 num = num + 1 0278 if num <> 10: 0279 raise error, "*** Unexpected number of loop iterations - got %d ***" % num 0280 progress("Finished testing counter") 0281 0282 def TestLocalVTable(ob): 0283 # Python doesn't fully implement this interface. 0284 if ob.DoubleString("foo") != "foofoo": 0285 raise error("couldn't foofoo") 0286 0287 ############################### 0288 ## 0289 ## Some vtable tests of the interface 0290 ## 0291 def TestVTable(clsctx=pythoncom.CLSCTX_ALL): 0292 # Any vtable interfaces marked as dual *should* be able to be 0293 # correctly implemented as IDispatch. 0294 ob = win32com.client.Dispatch("Python.Test.PyCOMTest") 0295 TestLocalVTable(ob) 0296 # Now test it via vtable - use some C++ code to help here as Python can't do it directly yet. 0297 tester = win32com.client.Dispatch("PyCOMTest.PyCOMTest") 0298 testee = pythoncom.CoCreateInstance("Python.Test.PyCOMTest", None, clsctx, pythoncom.IID_IUnknown) 0299 # check we fail gracefully with None passed. 0300 try: 0301 tester.TestMyInterface(None) 0302 except pythoncom.com_error, details: 0303 pass 0304 # and a real object. 0305 tester.TestMyInterface(testee) 0306 0307 def TestVTable2(): 0308 # We once crashed creating our object with the native interface as 0309 # the first IID specified. We must do it _after_ the tests, so that 0310 # Python has already had the gateway registered from last run. 0311 ob = win32com.client.Dispatch("Python.Test.PyCOMTest") 0312 iid = pythoncom.InterfaceNames["IPyCOMTest"] 0313 clsid = "Python.Test.PyCOMTest" 0314 clsctx = pythoncom.CLSCTX_SERVER 0315 try: 0316 testee = pythoncom.CoCreateInstance(clsid, None, clsctx, iid) 0317 except TypeError: 0318 # Python can't actually _use_ this interface yet, so this is 0319 # "expected". Any COM error is not. 0320 pass 0321 0322 def TestQueryInterface(long_lived_server = 0, iterations=5): 0323 tester = win32com.client.Dispatch("PyCOMTest.PyCOMTest") 0324 if long_lived_server: 0325 # Create a local server 0326 t0 = win32com.client.Dispatch("Python.Test.PyCOMTest", clsctx=pythoncom.CLSCTX_LOCAL_SERVER) 0327 # Request custom interfaces a number of times 0328 prompt = [ 0329 "Testing QueryInterface without long-lived local-server #%d of %d...", 0330 "Testing QueryInterface with long-lived local-server #%d of %d..." 0331 ] 0332 0333 for i in range(iterations): 0334 progress(prompt[long_lived_server!=0] % (i+1, iterations)) 0335 tester.TestQueryInterface() 0336 0337 class Tester(win32com.test.util.TestCase): 0338 def testVTableInProc(self): 0339 # We used to crash running this the second time - do it a few times 0340 for i in range(3): 0341 progress("Testing VTables in-process #%d..." % (i+1)) 0342 TestVTable(pythoncom.CLSCTX_INPROC_SERVER) 0343 def testVTableLocalServer(self): 0344 for i in range(3): 0345 progress("Testing VTables out-of-process #%d..." % (i+1)) 0346 TestVTable(pythoncom.CLSCTX_LOCAL_SERVER) 0347 def testVTable2(self): 0348 for i in range(3): 0349 TestVTable2() 0350 def testMultiQueryInterface(self): 0351 TestQueryInterface(0,6) 0352 # When we use the custom interface in the presence of a long-lived 0353 # local server, i.e. a local server that is already running when 0354 # we request an instance of our COM object, and remains afterwards, 0355 # then after repeated requests to create an instance of our object 0356 # the custom interface disappears -- i.e. QueryInterface fails with 0357 # E_NOINTERFACE. Set the upper range of the following test to 2 to 0358 # pass this test, i.e. TestQueryInterface(1,2) 0359 TestQueryInterface(1,6) 0360 def testDynamic(self): 0361 TestDynamic() 0362 def testGenerated(self): 0363 TestGenerated() 0364 0365 if __name__=='__main__': 0366 # XXX - todo - Complete hack to crank threading support. 0367 # Should NOT be necessary 0368 def NullThreadFunc(): 0369 pass 0370 import thread 0371 thread.start_new( NullThreadFunc, () ) 0372 0373 if "-v" in sys.argv: verbose = 1 0374 0375 win32com.test.util.testmain() 0376
Generated by PyXR 0.9.4