stability test is successfully crashing, ref_cycle test exposes cycles!
This commit is contained in:
parent
8dd7f07158
commit
82bd5ef584
@ -4,7 +4,7 @@ Test for unwanted reference cycles
|
|||||||
"""
|
"""
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import gc
|
import gc, weakref
|
||||||
app = pg.mkQApp()
|
app = pg.mkQApp()
|
||||||
|
|
||||||
def processEvents():
|
def processEvents():
|
||||||
@ -15,31 +15,46 @@ def processEvents():
|
|||||||
# manually.
|
# manually.
|
||||||
app.sendPostedEvents(None, pg.QtCore.QEvent.DeferredDelete)
|
app.sendPostedEvents(None, pg.QtCore.QEvent.DeferredDelete)
|
||||||
|
|
||||||
def test_PlotItem():
|
#def test_PlotItem():
|
||||||
for i in range(10):
|
#for i in range(10):
|
||||||
plt = pg.PlotItem()
|
#plt = pg.PlotItem()
|
||||||
plt.plot(np.random.normal(size=10000))
|
#plt.plot(np.random.normal(size=10000))
|
||||||
processEvents()
|
#processEvents()
|
||||||
|
|
||||||
ot = pg.debug.ObjTracker()
|
#ot = pg.debug.ObjTracker()
|
||||||
|
|
||||||
plots = []
|
#plots = []
|
||||||
for i in range(10):
|
#for i in range(10):
|
||||||
plt = pg.PlotItem()
|
#plt = pg.PlotItem()
|
||||||
plt.plot(np.random.normal(size=10000))
|
#plt.plot(np.random.normal(size=10000))
|
||||||
plots.append(plt)
|
#plots.append(plt)
|
||||||
processEvents()
|
#processEvents()
|
||||||
|
|
||||||
ot.diff()
|
#ot.diff()
|
||||||
|
|
||||||
del plots
|
#del plots
|
||||||
processEvents()
|
#processEvents()
|
||||||
|
|
||||||
ot.diff()
|
#ot.diff()
|
||||||
|
|
||||||
|
|
||||||
return ot
|
#return ot
|
||||||
|
|
||||||
|
def test_PlotWidget():
|
||||||
|
def mkref(*args, **kwds):
|
||||||
|
iv = pg.PlotWidget(*args, **kwds)
|
||||||
|
return weakref.ref(iv)
|
||||||
|
|
||||||
|
for i in range(100):
|
||||||
|
assert mkref()() is None
|
||||||
|
|
||||||
|
def test_ImageView():
|
||||||
|
def mkref(*args, **kwds):
|
||||||
|
iv = pg.ImageView(*args, **kwds)
|
||||||
|
return weakref.ref(iv)
|
||||||
|
|
||||||
|
for i in range(100):
|
||||||
|
assert mkref()() is None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
ot = test_PlotItem()
|
ot = test_PlotItem()
|
||||||
|
@ -6,34 +6,146 @@ the tear them down repeatedly.
|
|||||||
|
|
||||||
The purpose of this is to attempt to generate segmentation faults.
|
The purpose of this is to attempt to generate segmentation faults.
|
||||||
"""
|
"""
|
||||||
|
from PyQt4.QtTest import QTest
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
import random
|
from random import seed, randint
|
||||||
|
import sys, gc, weakref
|
||||||
|
|
||||||
random.seed(12345)
|
app = pg.mkQApp()
|
||||||
|
|
||||||
widgetTypes = [pg.PlotWidget, pg.ImageView, pg.GraphicsView, pg.QtGui.QWidget,
|
seed(12345)
|
||||||
pg.QtGui.QTreeWidget, pg.QtGui.QPushButton]
|
|
||||||
|
|
||||||
itemTypes = [pg.PlotCurveItem, pg.ImageItem, pg.PlotDataItem, pg.ViewBox,
|
widgetTypes = [
|
||||||
pg.QtGui.QGraphicsRectItem]
|
pg.PlotWidget,
|
||||||
|
pg.ImageView,
|
||||||
|
pg.GraphicsView,
|
||||||
|
pg.QtGui.QWidget,
|
||||||
|
pg.QtGui.QTreeWidget,
|
||||||
|
pg.QtGui.QPushButton,
|
||||||
|
]
|
||||||
|
|
||||||
while True:
|
itemTypes = [
|
||||||
action = random.randint(0,5)
|
pg.PlotCurveItem,
|
||||||
if action == 0:
|
pg.ImageItem,
|
||||||
# create a widget
|
pg.PlotDataItem,
|
||||||
pass
|
pg.ViewBox,
|
||||||
elif action == 1:
|
pg.QtGui.QGraphicsRectItem
|
||||||
# set parent (widget or None), possibly create a reference in either direction
|
]
|
||||||
pass
|
|
||||||
elif action == 2:
|
widgets = []
|
||||||
#
|
items = []
|
||||||
pass
|
allWidgets = weakref.WeakSet()
|
||||||
elif action == 3:
|
|
||||||
|
def test_stability():
|
||||||
|
global allWidgets
|
||||||
|
try:
|
||||||
|
gc.disable()
|
||||||
|
actions = [
|
||||||
|
createWidget,
|
||||||
|
#setParent,
|
||||||
|
forgetWidget,
|
||||||
|
showWidget,
|
||||||
|
processEvents,
|
||||||
|
#raiseException,
|
||||||
|
#addReference,
|
||||||
|
]
|
||||||
|
|
||||||
|
thread = WorkThread()
|
||||||
|
#thread.start()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
action = randItem(actions)
|
||||||
|
action()
|
||||||
|
print('[%d widgets alive]' % len(allWidgets))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
thread.kill()
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
sys.excepthook(*sys.exc_info())
|
||||||
|
finally:
|
||||||
|
gc.enable()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class WorkThread(pg.QtCore.QThread):
|
||||||
|
'''Intended to give the gc an opportunity to run from a non-gui thread.'''
|
||||||
|
def run(self):
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
i += 1
|
||||||
|
if (i % 1000000) == 0:
|
||||||
|
print('--worker--')
|
||||||
|
|
||||||
|
|
||||||
|
def randItem(items):
|
||||||
|
return items[randint(0, len(items)-1)]
|
||||||
|
|
||||||
|
def p(msg):
|
||||||
|
print(msg)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def createWidget():
|
||||||
|
p('create widget')
|
||||||
|
global widgets, allWidgets
|
||||||
|
widget = randItem(widgetTypes)()
|
||||||
|
widgets.append(widget)
|
||||||
|
allWidgets.add(widget)
|
||||||
|
p(" %s" % widget)
|
||||||
|
return widget
|
||||||
|
|
||||||
|
def setParent():
|
||||||
|
p('set parent')
|
||||||
|
global widgets
|
||||||
|
if len(widgets) < 2:
|
||||||
|
return
|
||||||
|
child = parent = None
|
||||||
|
while child is parent:
|
||||||
|
child = randItem(widgets)
|
||||||
|
parent = randItem(widgets)
|
||||||
|
p(" %s parent of %s" % (parent, child))
|
||||||
|
child.setParent(parent)
|
||||||
|
|
||||||
|
def forgetWidget():
|
||||||
|
p('forget widget')
|
||||||
|
global widgets
|
||||||
|
if len(widgets) < 1:
|
||||||
|
return
|
||||||
|
widget = randItem(widgets)
|
||||||
|
p(' %s' % widget)
|
||||||
|
widgets.remove(widget)
|
||||||
|
|
||||||
|
def showWidget():
|
||||||
|
p('show widget')
|
||||||
|
global widgets
|
||||||
|
if len(widgets) < 1:
|
||||||
|
return
|
||||||
|
widget = randItem(widgets)
|
||||||
|
p(' %s' % widget)
|
||||||
|
widget.show()
|
||||||
|
|
||||||
|
def processEvents():
|
||||||
|
p('process events')
|
||||||
|
QTest.qWait(25)
|
||||||
|
|
||||||
|
class TestException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def raiseException():
|
||||||
|
p('raise exception')
|
||||||
|
raise TestException("A test exception")
|
||||||
|
|
||||||
|
def addReference():
|
||||||
|
p('add reference')
|
||||||
|
global widgets
|
||||||
|
if len(widgets) < 1:
|
||||||
|
return
|
||||||
|
obj1 = randItem(widgets)
|
||||||
|
obj2 = randItem(widgets)
|
||||||
|
p(' %s -> %s' % (obj1, obj2))
|
||||||
|
obj1._testref = obj2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_stability()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user