1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
"""
PyQt/PySide stress test:
Create lots of random widgets and graphics items, connect them together randomly,
the tear them down repeatedly.
The purpose of this is to attempt to generate segmentation faults.
"""
import gc
import sys
import time
import weakref
from random import randint, seed
import pyqtgraph as pg
from pyqtgraph.Qt import QtTest
from pyqtgraph.util.garbage_collector import GarbageCollector
app = pg.mkQApp()
def test_garbage_collector():
GarbageCollector(interval=0.1)
time.sleep(1)
seed(12345)
widgetTypes = [
pg.PlotWidget,
pg.ImageView,
pg.GraphicsView,
pg.QtWidgets.QWidget,
pg.QtWidgets.QTreeWidget,
pg.QtWidgets.QPushButton,
]
itemTypes = [
pg.PlotCurveItem,
pg.ImageItem,
pg.PlotDataItem,
pg.ViewBox,
pg.QtWidgets.QGraphicsRectItem
]
widgets = []
items = []
allWidgets = weakref.WeakKeyDictionary()
def crashtest():
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, %d zombie]' % (len(allWidgets), len(allWidgets) - len(widgets)))
except KeyboardInterrupt:
print("Caught interrupt; send another to exit.")
try:
for _ in range(100):
QtTest.QTest.qWait(100)
except KeyboardInterrupt:
thread.terminate()
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
if len(widgets) > 50:
return None
widget = randItem(widgetTypes)()
widget.setWindowTitle(widget.__class__.__name__)
widgets.append(widget)
allWidgets[widget] = 1
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')
QtTest.QTest.qWait(25)
class TstException(Exception):
pass
def raiseException():
p('raise exception')
raise TstException("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
|