VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/python/test/test_test_component.py@ 43978

Last change on this file since 43978 was 11746, checked in by vboxsync, 16 years ago

export python lib to OSE

  • Property svn:eol-style set to native
File size: 25.3 KB
Line 
1# ***** BEGIN LICENSE BLOCK *****
2# Version: MPL 1.1/GPL 2.0/LGPL 2.1
3#
4# The contents of this file are subject to the Mozilla Public License Version
5# 1.1 (the "License"); you may not use this file except in compliance with
6# the License. You may obtain a copy of the License at
7# http://www.mozilla.org/MPL/
8#
9# Software distributed under the License is distributed on an "AS IS" basis,
10# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11# for the specific language governing rights and limitations under the
12# License.
13#
14# The Original Code is the Python XPCOM language bindings.
15#
16# The Initial Developer of the Original Code is
17# ActiveState Tool Corp.
18# Portions created by the Initial Developer are Copyright (C) 2000, 2001
19# the Initial Developer. All Rights Reserved.
20#
21# Contributor(s):
22# Mark Hammond <[email protected]> (original author)
23#
24# Alternatively, the contents of this file may be used under the terms of
25# either the GNU General Public License Version 2 or later (the "GPL"), or
26# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27# in which case the provisions of the GPL or the LGPL are applicable instead
28# of those above. If you wish to allow use of your version of this file only
29# under the terms of either the GPL or the LGPL, and not to allow others to
30# use your version of this file under the terms of the MPL, indicate your
31# decision by deleting the provisions above and replace them with the notice
32# and other provisions required by the GPL or the LGPL. If you do not delete
33# the provisions above, a recipient may use your version of this file under
34# the terms of any one of the MPL, the GPL or the LGPL.
35#
36# ***** END LICENSE BLOCK *****
37
38import sys, os, time
39import xpcom.components
40import xpcom._xpcom
41import xpcom.nsError
42
43MakeVariant = xpcom._xpcom.MakeVariant
44
45try:
46 import gc
47except ImportError:
48 gc = None
49
50num_errors = 0
51
52component_iid = xpcom.components.ID("{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}")
53new_iid = xpcom.components.ID("{2AF747D3-ECBC-457b-9AF9-5C5D80EDC360}")
54
55contractid = "Python.TestComponent"
56
57really_big_string = "This is really repetitive!" * 10000
58really_big_wstring = u"This is really repetitive!" * 10000
59extended_unicode_string = u"The Euro Symbol is '\u20ac'"
60
61# Exception raised when a -ve integer is converted to an unsigned C integer
62# (via an extension module). This changed in Python 2.2
63if sys.hexversion > 0x02010000:
64 UnsignedMismatchException = TypeError
65else:
66 UnsignedMismatchException = OverflowError
67
68def print_error(error):
69 print error
70 global num_errors
71 num_errors = num_errors + 1
72
73def _test_value(what, got, expecting):
74 ok = got == expecting
75 if type(got)==type(expecting)==type(0.0):
76 ok = abs(got-expecting) < 0.001
77 if not ok:
78 print_error("*** Error %s - got '%r', but expecting '%r'" % (what, got, expecting))
79
80def test_attribute(ob, attr_name, expected_init, new_value, new_value_really = None):
81 if xpcom.verbose:
82 print "Testing attribute %s" % (attr_name,)
83 if new_value_really is None:
84 new_value_really = new_value # Handy for eg bools - set a BOOL to 2, you still get back 1!
85
86 _test_value( "getting initial attribute value (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
87 setattr(ob, attr_name, new_value)
88 _test_value( "getting new attribute value (%s)" % (attr_name,), getattr(ob, attr_name), new_value_really)
89 # And set it back to the expected init.
90 setattr(ob, attr_name, expected_init)
91 _test_value( "getting back initial attribute value after change (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
92
93def test_string_attribute(ob, attr_name, expected_init, is_dumb_sz = False, ascii_only = False):
94 test_attribute(ob, attr_name, expected_init, "normal value")
95 val = "a null >\0<"
96 if is_dumb_sz:
97 expected = "a null >" # dumb strings are \0 terminated.
98 else:
99 expected = val
100 test_attribute(ob, attr_name, expected_init, val, expected)
101 test_attribute(ob, attr_name, expected_init, "")
102 test_attribute(ob, attr_name, expected_init, really_big_string)
103 test_attribute(ob, attr_name, expected_init, u"normal unicode value")
104 val = u"a null >\0<"
105 if is_dumb_sz:
106 expected = "a null >" # dumb strings are \0 terminated.
107 else:
108 expected = val
109 test_attribute(ob, attr_name, expected_init, val, expected)
110 test_attribute(ob, attr_name, expected_init, u"")
111 test_attribute(ob, attr_name, expected_init, really_big_wstring)
112 if not ascii_only:
113 test_attribute(ob, attr_name, expected_init, extended_unicode_string)
114
115def test_attribute_failure(ob, attr_name, new_value, expected_exception):
116 try:
117 setattr(ob, attr_name, new_value)
118 print_error("*** Setting attribute '%s' to '%r' didnt yield an exception!" % (attr_name, new_value) )
119 except:
120 exc_typ = sys.exc_info()[0]
121 exc_val = sys.exc_info()[1]
122 ok = issubclass(exc_typ, expected_exception)
123 if not ok:
124 print_error("*** Wrong exception setting '%s' to '%r'- got '%s: %s', expected '%s'" % (attr_name, new_value, exc_typ, exc_val, expected_exception))
125
126
127def test_method(method, args, expected_results):
128 if xpcom.verbose:
129 print "Testing %s%s" % (method.__name__, `args`)
130 ret = method(*args)
131 if ret != expected_results:
132 print_error("calling method %s - expected %r, but got %r" % (method.__name__, expected_results, ret))
133
134def test_int_method(meth):
135 test_method(meth, (0,0), (0,0,0))
136 test_method(meth, (1,1), (2,0,1))
137 test_method(meth, (5,2), (7,3,10))
138# test_method(meth, (2,5), (7,-3,10))
139
140def test_constant(ob, cname, val):
141 v = getattr(ob, cname)
142 if v != val:
143 print_error("Bad value for constant '%s' - got '%r'" % (cname, v))
144 try:
145 setattr(ob, cname, 0)
146 print_error("The object allowed us to set the constant '%s'" % (cname,))
147 except AttributeError:
148 pass
149
150def test_base_interface(c):
151 test_attribute(c, "boolean_value", 1, 0)
152 test_attribute(c, "boolean_value", 1, -1, 1) # Set a bool to anything, you should always get back 0 or 1
153 test_attribute(c, "boolean_value", 1, 4, 1) # Set a bool to anything, you should always get back 0 or 1
154 test_attribute(c, "boolean_value", 1, "1", 1) # This works by virtual of PyNumber_Int - not sure I agree, but...
155 test_attribute_failure(c, "boolean_value", "boo", ValueError)
156 test_attribute_failure(c, "boolean_value", test_base_interface, TypeError)
157
158 test_attribute(c, "octet_value", 2, 5)
159 test_attribute(c, "octet_value", 2, 0)
160 test_attribute(c, "octet_value", 2, 128) # octet is unsigned 8 bit
161 test_attribute(c, "octet_value", 2, 255) # octet is unsigned 8 bit
162 test_attribute(c, "octet_value", 2, -1, 255) # octet is unsigned 8 bit
163 test_attribute_failure(c, "octet_value", "boo", ValueError)
164
165 test_attribute(c, "short_value", 3, 10)
166 test_attribute(c, "short_value", 3, -1) # 16 bit signed
167 test_attribute(c, "short_value", 3, 0xFFFF, -1) # 16 bit signed
168 test_attribute(c, "short_value", 3, 0L)
169 test_attribute(c, "short_value", 3, 1L)
170 test_attribute(c, "short_value", 3, -1L)
171 test_attribute(c, "short_value", 3, 0xFFFFL, -1)
172 test_attribute_failure(c, "short_value", "boo", ValueError)
173
174 test_attribute(c, "ushort_value", 4, 5)
175 test_attribute(c, "ushort_value", 4, 0)
176 test_attribute(c, "ushort_value", 4, -1, 0xFFFF) # 16 bit signed
177 test_attribute(c, "ushort_value", 4, 0xFFFF) # 16 bit signed
178 test_attribute(c, "ushort_value", 4, 0L)
179 test_attribute(c, "ushort_value", 4, 1L)
180 test_attribute(c, "ushort_value", 4, -1L, 0xFFFF)
181 test_attribute_failure(c, "ushort_value", "boo", ValueError)
182
183 test_attribute(c, "long_value", 5, 7)
184 test_attribute(c, "long_value", 5, 0)
185 test_attribute(c, "long_value", 5, -1, -1) # 32 bit signed.
186 test_attribute(c, "long_value", 5, -1) # 32 bit signed.
187 test_attribute(c, "long_value", 5, 0L)
188 test_attribute(c, "long_value", 5, 1L)
189 test_attribute(c, "long_value", 5, -1L)
190 test_attribute_failure(c, "long_value", 0xFFFFL * 0xFFFF, OverflowError) # long int too long to convert
191 test_attribute_failure(c, "long_value", "boo", ValueError)
192
193 test_attribute(c, "ulong_value", 6, 7)
194 test_attribute(c, "ulong_value", 6, 0)
195 test_attribute(c, "ulong_value", 6, -1) # 32 bit signed.
196 test_attribute_failure(c, "ulong_value", "boo", ValueError)
197
198 test_attribute(c, "long_long_value", 7, 8)
199 test_attribute(c, "long_long_value", 7, 0)
200 test_attribute(c, "long_long_value", 7, -1)
201 test_attribute(c, "long_long_value", 7, 0xFFFF)
202 test_attribute(c, "long_long_value", 7, 0xFFFFL * 2)
203 test_attribute_failure(c, "long_long_value", 0xFFFFL * 0xFFFF * 0xFFFF * 0xFFFF, OverflowError) # long int too long to convert
204 test_attribute_failure(c, "long_long_value", "boo", ValueError)
205
206 test_attribute(c, "ulong_long_value", 8, 9)
207 test_attribute(c, "ulong_long_value", 8, 0)
208 test_attribute_failure(c, "ulong_long_value", "boo", ValueError)
209 test_attribute_failure(c, "ulong_long_value", -1, UnsignedMismatchException) # can't convert negative value to unsigned long)
210
211 test_attribute(c, "float_value", 9.0, 10.2)
212 test_attribute(c, "float_value", 9.0, 0)
213 test_attribute(c, "float_value", 9.0, -1)
214 test_attribute(c, "float_value", 9.0, 1L)
215 test_attribute_failure(c, "float_value", "boo", ValueError)
216
217 test_attribute(c, "double_value", 10.0, 9.0)
218 test_attribute(c, "double_value", 10.0, 0)
219 test_attribute(c, "double_value", 10.0, -1)
220 test_attribute(c, "double_value", 10.0, 1L)
221 test_attribute_failure(c, "double_value", "boo", ValueError)
222
223 test_attribute(c, "char_value", "a", "b")
224 test_attribute(c, "char_value", "a", "\0")
225 test_attribute_failure(c, "char_value", "xy", ValueError)
226 test_attribute(c, "char_value", "a", u"c")
227 test_attribute(c, "char_value", "a", u"\0")
228 test_attribute_failure(c, "char_value", u"xy", ValueError)
229
230 test_attribute(c, "wchar_value", "b", "a")
231 test_attribute(c, "wchar_value", "b", "\0")
232 test_attribute_failure(c, "wchar_value", "hi", ValueError)
233 test_attribute(c, "wchar_value", "b", u"a")
234 test_attribute(c, "wchar_value", "b", u"\0")
235 test_attribute_failure(c, "wchar_value", u"hi", ValueError)
236
237 test_string_attribute(c, "string_value", "cee", is_dumb_sz = True, ascii_only = True)
238 test_string_attribute(c, "wstring_value", "dee", is_dumb_sz = True)
239 test_string_attribute(c, "astring_value", "astring")
240 test_string_attribute(c, "acstring_value", "acstring", ascii_only = True)
241
242 test_string_attribute(c, "utf8string_value", "utf8string")
243 # Test a string already encoded gets through correctly.
244 test_attribute(c, "utf8string_value", "utf8string", extended_unicode_string.encode("utf8"), extended_unicode_string)
245
246 # This will fail internal string representation :( Test we don't crash
247 try:
248 c.wstring_value = "a big char >" + chr(129) + "<"
249 print_error("strings with chars > 128 appear to have stopped failing?")
250 except UnicodeError:
251 pass
252
253 test_attribute(c, "iid_value", component_iid, new_iid)
254 test_attribute(c, "iid_value", component_iid, str(new_iid), new_iid)
255 test_attribute(c, "iid_value", component_iid, xpcom._xpcom.IID(new_iid))
256
257 test_attribute_failure(c, "no_attribute", "boo", AttributeError)
258
259 test_attribute(c, "interface_value", None, c)
260 test_attribute_failure(c, "interface_value", 2, TypeError)
261
262 test_attribute(c, "isupports_value", None, c)
263
264 # The methods
265 test_method(c.do_boolean, (0,1), (1,0,1))
266 test_method(c.do_boolean, (1,0), (1,0,1))
267 test_method(c.do_boolean, (1,1), (0,1,0))
268
269 test_int_method(c.do_octet)
270 test_int_method(c.do_short)
271
272 test_int_method(c.do_unsigned_short)
273 test_int_method(c.do_long)
274 test_int_method(c.do_unsigned_long)
275 test_int_method(c.do_long_long)
276 test_int_method(c.do_unsigned_long)
277 test_int_method(c.do_float)
278 test_int_method(c.do_double)
279
280 test_method(c.do_char, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
281 test_method(c.do_char, ("A", "\0"), ("A", "\0","A") )
282 test_method(c.do_wchar, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
283 test_method(c.do_wchar, ("A", "\0"), ("A", "\0","A") )
284
285 test_method(c.do_string, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
286 test_method(c.do_string, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
287 test_method(c.do_string, (None, u"Python"), ("Python", None, "Python") )
288 test_method(c.do_string, (None, really_big_string), (really_big_string, None, really_big_string) )
289 test_method(c.do_string, (None, really_big_wstring), (really_big_string, None, really_big_string) )
290 test_method(c.do_wstring, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
291 test_method(c.do_wstring, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
292 test_method(c.do_string, (None, really_big_wstring), (really_big_wstring, None, really_big_wstring) )
293 test_method(c.do_string, (None, really_big_string), (really_big_wstring, None, really_big_wstring) )
294 test_method(c.do_nsIIDRef, (component_iid, new_iid), (component_iid, component_iid, new_iid))
295 test_method(c.do_nsIIDRef, (new_iid, component_iid), (new_iid, component_iid, component_iid))
296 test_method(c.do_nsIPythonTestInterface, (None, None), (None, None, c))
297 test_method(c.do_nsIPythonTestInterface, (c, c), (c, c, c))
298 test_method(c.do_nsISupports, (None, None), (c, None, None))
299 test_method(c.do_nsISupports, (c,c), (c, c, c))
300 test_method(c.do_nsISupportsIs, (xpcom._xpcom.IID_nsISupports,), c)
301 test_method(c.do_nsISupportsIs, (xpcom.components.interfaces.nsIPythonTestInterface,), c)
302## test_method(c.do_nsISupportsIs2, (xpcom.components.interfaces.nsIPythonTestInterface,c), (xpcom.components.interfaces.nsIPythonTestInterface,c))
303## test_method(c.do_nsISupportsIs3, (c,), (xpcom.components.interfaces.nsIPythonTestInterface,c))
304## test_method(c.do_nsISupportsIs4, (), (xpcom.components.interfaces.nsIPythonTestInterface,c))
305 # Test the constants.
306 test_constant(c, "One", 1)
307 test_constant(c, "Two", 2)
308 test_constant(c, "MinusOne", -1)
309 test_constant(c, "BigLong", 0x7FFFFFFF)
310 test_constant(c, "BiggerLong", -1)
311 test_constant(c, "BigULong", -1)
312 # Test the components.Interfaces semantics
313 i = xpcom.components.interfaces.nsIPythonTestInterface
314 test_constant(i, "One", 1)
315 test_constant(i, "Two", 2)
316 test_constant(i, "MinusOne", -1)
317 test_constant(i, "BigLong", 0x7FFFFFFF)
318 test_constant(i, "BigULong", -1)
319
320def test_derived_interface(c, test_flat = 0):
321 val = "Hello\0there"
322 expected = val * 2
323
324 test_method(c.DoubleString, (val,), expected)
325 test_method(c.DoubleString2, (val,), expected)
326 test_method(c.DoubleString3, (val,), expected)
327 test_method(c.DoubleString4, (val,), expected)
328 test_method(c.UpString, (val,), val.upper())
329 test_method(c.UpString2, (val,), val.upper())
330 test_method(c.GetFixedString, (20,), "A"*20)
331 val = u"Hello\0there"
332 expected = val * 2
333 test_method(c.DoubleWideString, (val,), expected)
334 test_method(c.DoubleWideString2, (val,), expected)
335 test_method(c.DoubleWideString3, (val,), expected)
336 test_method(c.DoubleWideString4, (val,), expected)
337 test_method(c.UpWideString, (val,), val.upper())
338 test_method(c.UpWideString2, (val,), val.upper())
339 test_method(c.GetFixedWideString, (20,), u"A"*20)
340 val = extended_unicode_string
341 test_method(c.CopyUTF8String, ("foo",), "foo")
342 test_method(c.CopyUTF8String, (u"foo",), "foo")
343 test_method(c.CopyUTF8String, (val,), val)
344 test_method(c.CopyUTF8String, (val.encode("utf8"),), val)
345 test_method(c.CopyUTF8String2, ("foo",), "foo")
346 test_method(c.CopyUTF8String2, (u"foo",), "foo")
347 test_method(c.CopyUTF8String2, (val,), val)
348 test_method(c.CopyUTF8String2, (val.encode("utf8"),), val)
349 items = [1,2,3,4,5]
350 test_method(c.MultiplyEachItemInIntegerArray, (3, items,), map(lambda i:i*3, items))
351
352 test_method(c.MultiplyEachItemInIntegerArrayAndAppend, (3, items), items + map(lambda i:i*3, items))
353 items = "Hello from Python".split()
354 expected = map( lambda x: x*2, items)
355 test_method(c.DoubleStringArray, (items,), expected)
356
357 test_method(c.CompareStringArrays, (items, items), cmp(items, items))
358 # Can we pass lists and tuples correctly?
359 test_method(c.CompareStringArrays, (items, tuple(items)), cmp(items, items))
360 items2 = ["Not", "the", "same"]
361 test_method(c.CompareStringArrays, (items, items2), cmp(items, items2))
362
363 expected = items[:]
364 expected.reverse()
365 test_method(c.ReverseStringArray, (items,), expected)
366
367 expected = "Hello from the Python test component".split()
368 test_method(c.GetStrings, (), expected)
369
370 val = "Hello\0there"
371 test_method(c.UpOctetArray, (val,), val.upper())
372 test_method(c.UpOctetArray, (unicode(val),), val.upper())
373 # Passing Unicode objects here used to cause us grief.
374 test_method(c.UpOctetArray2, (val,), val.upper())
375
376 test_method(c.CheckInterfaceArray, ((c, c),), 1)
377 test_method(c.CheckInterfaceArray, ((c, None),), 0)
378 test_method(c.CheckInterfaceArray, ((),), 1)
379 test_method(c.CopyInterfaceArray, ((c, c),), [c,c])
380
381 test_method(c.GetInterfaceArray, (), [c,c,c, None])
382 test_method(c.ExtendInterfaceArray, ((c,c,c, None),), [c,c,c,None,c,c,c,None] )
383
384 expected = [xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings, xpcom.components.classes[contractid].clsid]
385 test_method(c.GetIIDArray, (), expected)
386
387 val = [xpcom.components.interfaces.nsIPythonTestInterfaceExtra, xpcom.components.classes[contractid].clsid]
388 expected = val * 2
389 test_method(c.ExtendIIDArray, (val,), expected)
390
391 test_method(c.GetArrays, (), ( [1,2,3], [4,5,6] ) )
392 test_method(c.CopyArray, ([1,2,3],), [1,2,3] )
393 test_method(c.CopyAndDoubleArray, ([1,2,3],), [1,2,3,1,2,3] )
394 test_method(c.AppendArray, ([1,2,3],), [1,2,3])
395 test_method(c.AppendArray, ([1,2,3],[4,5,6]), [1,2,3,4,5,6])
396
397 test_method(c.CopyVariant, (None,), None)
398 test_method(c.CopyVariant, (1,), 1)
399 test_method(c.CopyVariant, (1.0,), 1.0)
400 test_method(c.CopyVariant, (-1,), -1)
401 test_method(c.CopyVariant, (sys.maxint+1,), sys.maxint+1)
402 test_method(c.CopyVariant, ("foo",), "foo")
403 test_method(c.CopyVariant, (u"foo",), u"foo")
404 test_method(c.CopyVariant, (c,), c)
405 test_method(c.CopyVariant, (component_iid,), component_iid)
406 test_method(c.CopyVariant, ((1,2),), [1,2])
407 test_method(c.CopyVariant, ((1.2,2.1),), [1.2,2.1])
408 test_method(c.CopyVariant, (("foo","bar"),), ["foo", "bar"])
409 test_method(c.CopyVariant, ((component_iid,component_iid),), [component_iid,component_iid])
410 test_method(c.CopyVariant, ((c,c),), [c,c])
411 sup = c.queryInterface(xpcom.components.interfaces.nsISupports)._comobj_
412 test_method(c.CopyVariant, ((sup, sup),), [sup,sup])
413 test_method(c.AppendVariant, (1,2), 3)
414 test_method(c.AppendVariant, ((1,2),(3,4)), 10)
415 test_method(c.AppendVariant, ("bar", "foo"), "foobar")
416 test_method(c.AppendVariant, (None, None), None)
417
418 test_method(c.SumVariants, ([],), None)
419 # Array's dont expose their interface, so we are unable to auto-wrap
420 # variant arrays, as they aren't aware if the IID of the array
421 test_method(c.SumVariants, ([MakeVariant(1),MakeVariant(2),MakeVariant(3)],), 6)
422 test_method(c.SumVariants, ([MakeVariant('foo'), MakeVariant('bar')],), 'foobar')
423
424 if not test_flat:
425 c = c.queryInterface(xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings)
426# NULL DOM strings don't work yet.
427# test_method(c.GetDOMStringResult, (-1,), None)
428 test_method(c.GetDOMStringResult, (3,), "PPP")
429# test_method(c.GetDOMStringOut, (-1,), None)
430 test_method(c.GetDOMStringOut, (4,), "yyyy")
431 val = "Hello there"
432 test_method(c.GetDOMStringLength, (val,), len(val))
433 test_method(c.GetDOMStringRefLength, (val,), len(val))
434 test_method(c.GetDOMStringPtrLength, (val,), len(val))
435 test_method(c.ConcatDOMStrings, (val,val), val+val)
436 test_attribute(c, "domstring_value", "dom", "new dom")
437 if c.domstring_value_ro != "dom":
438 print "Read-only DOMString not correct - got", c.domstring_ro
439 try:
440 c.dom_string_ro = "new dom"
441 print "Managed to set a readonly attribute - eek!"
442 except AttributeError:
443 pass
444 except:
445 print "Unexpected exception when setting readonly attribute: %s: %s" % (sys.exc_info()[0], sys.exc_info()[1])
446 if c.domstring_value_ro != "dom":
447 print "Read-only DOMString not correct after failed set attempt - got", c.domstring_ro
448
449def do_test_failures():
450 c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
451 try:
452 ret = c.do_nsISupportsIs( xpcom._xpcom.IID_nsIInterfaceInfoManager )
453 print "*** got", ret, "***"
454 raise RuntimeError, "We worked when using an IID we dont support!?!"
455 except xpcom.Exception, details:
456 if details.errno != xpcom.nsError.NS_ERROR_NO_INTERFACE:
457 raise RuntimeError, "Wrong COM exception type: %r" % (details,)
458
459def test_failures():
460 # This extra stack-frame ensures Python cleans up sys.last_traceback etc
461 do_test_failures()
462
463def test_all():
464 c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterface)
465 test_base_interface(c)
466 # Now create an instance using the derived IID, and test that.
467 c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
468 test_base_interface(c)
469 test_derived_interface(c)
470 # Now create an instance and test interface flattening.
471 c = xpcom.components.classes[contractid].createInstance()
472 test_base_interface(c)
473 test_derived_interface(c, test_flat=1)
474
475 # We had a bug where a "set" of an attribute before a "get" failed.
476 # Don't let it happen again :)
477 c = xpcom.components.classes[contractid].createInstance()
478 c.boolean_value = 0
479
480 # This name is used in exceptions etc - make sure we got it from nsIClassInfo OK.
481 assert c._object_name_ == "Python.TestComponent"
482
483 test_failures()
484
485try:
486 from sys import gettotalrefcount
487except ImportError:
488 # Not a Debug build - assume no references (can't be leaks then :-)
489 def gettotalrefcount():
490 return 0
491
492from pyxpcom_test_tools import getmemusage
493
494def test_from_js():
495 # Ensure we can find the js test script - same dir as this!
496 # Assume the path of sys.argv[0] is where we can find the js test code.
497 # (Running under the regression test is a little painful)
498 script_dir = os.path.split(sys.argv[0])[0]
499 fname = os.path.join( script_dir, "test_test_component.js")
500 if not os.path.isfile(fname):
501 raise RuntimeError, "Can not find '%s'" % (fname,)
502 # Note we _dont_ pump the test output out, as debug "xpcshell" spews
503 # extra debug info that will cause our output comparison to fail.
504 data = os.popen('xpcshell "' + fname + '"').readlines()
505 good = 0
506 for line in data:
507 if line.strip() == "javascript successfully tested the Python test component.":
508 good = 1
509 if not good:
510 print "** The javascript test appeared to fail! Test output follows **"
511 print "".join(data)
512 print "** End of javascript test output **"
513 raise RuntimeError, "test failed"
514
515def doit(num_loops = -1):
516 if "-v" in sys.argv: # Hack the verbose flag for the server
517 xpcom.verbose = 1
518 # Do the test lots of times - can help shake-out ref-count bugs.
519 if num_loops == -1: num_loops = 5
520 for i in xrange(num_loops):
521 test_all()
522
523 if i==0:
524 # First loop is likely to "leak" as we cache things.
525 # Leaking after that is a problem.
526 if gc is not None:
527 gc.collect()
528 num_refs = gettotalrefcount()
529 mem_usage = getmemusage()
530
531 if num_errors:
532 break
533
534 if gc is not None:
535 gc.collect()
536
537 lost = gettotalrefcount() - num_refs
538 # Sometimes we get spurious counts off by 1 or 2.
539 # This can't indicate a real leak, as we have looped
540 # more than twice!
541 if abs(lost)>3: # 2 or 3 :)
542 print "*** Lost %d references" % (lost,)
543
544 # sleep to allow the OS to recover
545 time.sleep(1)
546 mem_lost = getmemusage() - mem_usage
547 # working set size is fickle, and when we were leaking strings, this test
548 # would report a leak of 100MB. So we allow a 3MB buffer - but even this
549 # may still occasionally report spurious warnings. If you are really
550 # worried, bump the counter to a huge value, and if there is a leak it will
551 # show.
552 if mem_lost > 3000000:
553 print "*** Lost %.6f MB of memory" % (mem_lost/1000000.0,)
554
555 assert num_errors==0, "There were %d errors testing the Python component" % (num_errors,)
556
557def suite():
558 from pyxpcom_test_tools import suite_from_functions
559 return suite_from_functions(doit, test_from_js)
560
561if __name__=='__main__':
562 num_iters = 10 # times times is *lots* - we do a fair bit of work!
563 if __name__=='__main__' and len(sys.argv) > 1:
564 num_iters = int(sys.argv[1])
565
566 print "Testing the Python.TestComponent component"
567 doit(num_iters)
568 print "The Python test component worked."
569 test_from_js()
570 print "JS successfully used our Python test component."
571 xpcom._xpcom.NS_ShutdownXPCOM()
572 ni = xpcom._xpcom._GetInterfaceCount()
573 ng = xpcom._xpcom._GetGatewayCount()
574 if ni or ng:
575 print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette