Back to index

lightning-sunbird  0.9+nobinonly
test_weakreferences.py
Go to the documentation of this file.
00001 # ***** BEGIN LICENSE BLOCK *****
00002 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003 #
00004 # The contents of this file are subject to the Mozilla Public License Version
00005 # 1.1 (the "License"); you may not use this file except in compliance with
00006 # the License. You may obtain a copy of the License at
00007 # http://www.mozilla.org/MPL/
00008 #
00009 # Software distributed under the License is distributed on an "AS IS" basis,
00010 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011 # for the specific language governing rights and limitations under the
00012 # License.
00013 #
00014 # The Original Code is the Python XPCOM language bindings.
00015 #
00016 # The Initial Developer of the Original Code is
00017 # ActiveState Tool Corp.
00018 # Portions created by the Initial Developer are Copyright (C) 2000, 2001
00019 # the Initial Developer. All Rights Reserved.
00020 #
00021 # Contributor(s):
00022 #   Mark Hammond <markh@activestate.com> (original author)
00023 #
00024 # Alternatively, the contents of this file may be used under the terms of
00025 # either the GNU General Public License Version 2 or later (the "GPL"), or
00026 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027 # in which case the provisions of the GPL or the LGPL are applicable instead
00028 # of those above. If you wish to allow use of your version of this file only
00029 # under the terms of either the GPL or the LGPL, and not to allow others to
00030 # use your version of this file under the terms of the MPL, indicate your
00031 # decision by deleting the provisions above and replace them with the notice
00032 # and other provisions required by the GPL or the LGPL. If you do not delete
00033 # the provisions above, a recipient may use your version of this file under
00034 # the terms of any one of the MPL, the GPL or the LGPL.
00035 #
00036 # ***** END LICENSE BLOCK *****
00037 
00038 # test_weakreferences.py - Test our weak reference implementation.
00039 from xpcom import components, _xpcom
00040 import xpcom.server, xpcom.client
00041 
00042 try:
00043     from sys import gettotalrefcount
00044 except ImportError:
00045     # Not a Debug build - assume no references (can't be leaks then :-)
00046     gettotalrefcount = lambda: 0
00047 
00048 num_alive = 0
00049 
00050 class koTestSimple:
00051     _com_interfaces_ = [components.interfaces.nsIInputStream]
00052     def __init__(self):
00053         global num_alive
00054         num_alive += 1
00055     def __del__(self):
00056         global num_alive
00057         num_alive -= 1
00058     def close( self ):
00059         pass
00060 
00061 def test():
00062     ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsIInputStream)
00063 
00064     if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00065 
00066     # Check we can create a weak reference to our object.
00067     wr = xpcom.client.WeakReference(ob)
00068     if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00069 
00070     # Check we can call methods via the weak reference.
00071     if wr() is None: raise RuntimeError, "Our weak-reference is returning None before it should!"
00072     wr().close()
00073 
00074     ob  = None # This should kill the object.    
00075     if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00076     if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
00077 
00078     # Now a test that we can get a _new_ interface from the weak reference - ie,
00079     # an IID the real object has never previously been queried for
00080     # (this behaviour previously caused a bug - never again ;-)
00081     ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsISupports)
00082     if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00083     wr = xpcom.client.WeakReference(ob, components.interfaces.nsIInputStream)
00084     if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00085     wr() # This would die once upon a time ;-)
00086     ob  = None # This should kill the object.    
00087     if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
00088     if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
00089 
00090 def test_refcount(num_loops=-1):
00091     # Do the test lots of times - can help shake-out ref-count bugs.
00092     if num_loops == -1: num_loops = 10
00093     for i in xrange(num_loops):
00094         test()
00095 
00096         if i==0:
00097             # First loop is likely to "leak" as we cache things.
00098             # Leaking after that is a problem.
00099             num_refs = gettotalrefcount()
00100 
00101     lost = gettotalrefcount() - num_refs
00102     # Sometimes we get spurious counts off by 1 or 2.
00103     # This can't indicate a real leak, as we have looped
00104     # more than twice!
00105     if abs(lost)>2:
00106         print "*** Lost %d references" % (lost,)
00107     
00108 test_refcount()
00109 
00110 print "Weak-reference tests appear to have worked!"
00111 if __name__=='__main__':
00112     _xpcom.NS_ShutdownXPCOM()
00113     ni = xpcom._xpcom._GetInterfaceCount()
00114     ng = xpcom._xpcom._GetGatewayCount()
00115     if ni or ng:
00116         print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)