diff options
Diffstat (limited to 'sources/pyside6/tests/util')
-rw-r--r-- | sources/pyside6/tests/util/color.py | 14 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/__init__.py | 1 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/basicpyslotcase.py | 33 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/docmodifier.py | 91 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/helper.py | 37 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/helper.pyproject | 5 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/timedqapplication.py | 27 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/timedqguiapplication.py | 27 | ||||
-rw-r--r-- | sources/pyside6/tests/util/helper/usesqapplication.py | 43 | ||||
-rw-r--r-- | sources/pyside6/tests/util/httpd.py | 153 | ||||
-rw-r--r-- | sources/pyside6/tests/util/processtimer.py | 54 | ||||
-rwxr-xr-x | sources/pyside6/tests/util/rename_imports.sh | 16 | ||||
-rw-r--r-- | sources/pyside6/tests/util/test_processtimer.py | 73 | ||||
-rw-r--r-- | sources/pyside6/tests/util/valgrind-python.supp | 349 |
14 files changed, 923 insertions, 0 deletions
diff --git a/sources/pyside6/tests/util/color.py b/sources/pyside6/tests/util/color.py new file mode 100644 index 000000000..e85be28f3 --- /dev/null +++ b/sources/pyside6/tests/util/color.py @@ -0,0 +1,14 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Function to print a colored line to terminal''' + + +def print_colored(message): + print(f'\033[0;31m{message}\033[m') # red + + +if __name__ == '__main__': + print('42 - the answer') + print_colored("But what's the question?") + print('Hum?') diff --git a/sources/pyside6/tests/util/helper/__init__.py b/sources/pyside6/tests/util/helper/__init__.py new file mode 100644 index 000000000..218d8921e --- /dev/null +++ b/sources/pyside6/tests/util/helper/__init__.py @@ -0,0 +1 @@ +# This file intentionally left blank. diff --git a/sources/pyside6/tests/util/helper/basicpyslotcase.py b/sources/pyside6/tests/util/helper/basicpyslotcase.py new file mode 100644 index 000000000..500735c3a --- /dev/null +++ b/sources/pyside6/tests/util/helper/basicpyslotcase.py @@ -0,0 +1,33 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import gc + + +class BasicPySlotCase(object): + '''Base class that tests python slots and signal emissions. + + Python slots are defined as any callable passed to QObject.connect(). + ''' + def setUp(self): + self.called = False + + def tearDown(self): + try: + del self.args + except: + pass + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + + def cb(self, *args): + '''Simple callback with arbitrary arguments. + + The test function must setup the 'args' attribute with a sequence + containing the arguments expected to be received by this slot. + Currently only a single connection is supported. + ''' + if tuple(self.args) == args: + self.called = True + else: + raise ValueError('Invalid arguments for callback') diff --git a/sources/pyside6/tests/util/helper/docmodifier.py b/sources/pyside6/tests/util/helper/docmodifier.py new file mode 100644 index 000000000..cfb665640 --- /dev/null +++ b/sources/pyside6/tests/util/helper/docmodifier.py @@ -0,0 +1,91 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Helper metaclass do 'decorate' docstrings from base test case classes''' + +import types + + +def copy_func(func): + '''Helper function to copy a function object (except docstring)''' + return types.FunctionType(func.func_code, func.func_globals, func.func_name, + func.func_defaults, func.func_closure) + + +class DocModifier(type): + '''Metaclass for modifiying method documentation. + + It allows the managed class to modify the method documentation, adding + prefixes and suffixes to a given set of methods. + + For example, you have some unittest.TestCases that run on different set + of data. These methods could be written once in a base class and the + inheriting class just setup different setUp/tearDown methods with the + proper data. To differentiate the methods when using docstrings, you + can add a suffix or prefix to the docstring. + + Variables in the implementing class: + + doc_prefix - The prefix to the docstring + doc_suffix - The suffix to the docstring + doc_filter - The function to filter the methods. If not provided, this + no docstrings are changed.''' + + def __new__(mcs, name, bases, dct): + + # FIXME currently we have to define doc_filter on each subclass + filter_function = dct.get('doc_filter') + if not filter_function: + filter_function = lambda x: False + + for base in bases: + for attr in [x for x in base.__dict__ if filter_function(x)]: + original = getattr(base, attr) + + if original.__doc__: + copy = copy_func(original) + copy.__doc__ = (dct.get('doc_prefix', '') + + original.__doc__ + + dct.get('doc_suffix', '')) + dct[attr] = copy + + return type.__new__(mcs, name, bases, dct) + + def __init__(mcs, name, bases, dct): + super(DocModifier, mcs).__init__(name, bases, dct) + + +if __name__ == '__main__': + + # tests + class BaseTest(object): + __metaclass__ = DocModifier + + def testBase(self): + '''base''' + + def testWithoutDoc(self): + pass + + class Implementing(BaseTest): + + doc_filter = lambda x: x.startswith('test') + doc_prefix = 'prefix' + doc_suffix = 'suffix' + + class OnlyPrefix(BaseTest): + + doc_filter = lambda x: x.startswith('test') + doc_prefix = 'prefix' + + class OnlySuffix(BaseTest): + + doc_filter = lambda x: x.startswith('test') + doc_suffix = 'suffix' + + assert (Implementing.testBase.__doc__ == 'prefixbasesuffix') + assert (Implementing.testWithoutDoc.__doc__ == None) + assert (OnlySuffix.testBase.__doc__ == 'basesuffix') + assert (OnlySuffix.testWithoutDoc.__doc__ == None) + assert (OnlyPrefix.testBase.__doc__ == 'prefixbase') + assert (OnlyPrefix.testWithoutDoc.__doc__ == None) diff --git a/sources/pyside6/tests/util/helper/helper.py b/sources/pyside6/tests/util/helper/helper.py new file mode 100644 index 000000000..f80753f1f --- /dev/null +++ b/sources/pyside6/tests/util/helper/helper.py @@ -0,0 +1,37 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Helper classes and functions''' + +import os +from random import randint + + +def adjust_filename(filename, orig_mod_filename): + dirpath = os.path.dirname(os.path.abspath(orig_mod_filename)) + return os.path.join(dirpath, filename) + + +def _join_qml_errors(errors): + '''Return an error string from a list of QQmlError''' + result = '' + for i, error in enumerate(errors): + if i: + result += ', ' + result += error.toString() + return result + + +def quickview_errorstring(quickview): + '''Return an error string from a QQuickView''' + return _join_qml_errors(quickview.errors()) + + +def qmlcomponent_errorstring(component): + '''Return an error string from a QQmlComponent''' + return _join_qml_errors(component.errors()) + + +def random_string(size=5): + '''Generate random string with the given size''' + return ''.join(map(chr, [randint(33, 126) for x in range(size)])) diff --git a/sources/pyside6/tests/util/helper/helper.pyproject b/sources/pyside6/tests/util/helper/helper.pyproject new file mode 100644 index 000000000..dc23d87a5 --- /dev/null +++ b/sources/pyside6/tests/util/helper/helper.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["basicpyslotcase.py", "docmodifier.py", "helper.py", + "timedqapplication.py", "usesqapplication.py", "usesqcoreapplication.py", + "usesqguiapplication.py" ] +} diff --git a/sources/pyside6/tests/util/helper/timedqapplication.py b/sources/pyside6/tests/util/helper/timedqapplication.py new file mode 100644 index 000000000..d9250a9e0 --- /dev/null +++ b/sources/pyside6/tests/util/helper/timedqapplication.py @@ -0,0 +1,27 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Helper classes and functions''' + +import gc +import unittest + +from PySide6.QtCore import QTimer +from PySide6.QtWidgets import QApplication + + +class TimedQApplication(unittest.TestCase): + '''Helper class with timed QApplication exec loop''' + + def setUp(self, timeout=100): + '''Setups this Application. + + timeout - timeout in milisseconds''' + self.app = QApplication.instance() or QApplication([]) + QTimer.singleShot(timeout, self.app.quit) + + def tearDown(self): + '''Delete resources''' + del self.app + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() diff --git a/sources/pyside6/tests/util/helper/timedqguiapplication.py b/sources/pyside6/tests/util/helper/timedqguiapplication.py new file mode 100644 index 000000000..3d9a4217c --- /dev/null +++ b/sources/pyside6/tests/util/helper/timedqguiapplication.py @@ -0,0 +1,27 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Helper classes and functions''' + +import gc +import unittest + +from PySide6.QtCore import QTimer +from PySide6.QtGui import QGuiApplication + + +class TimedQGuiApplication(unittest.TestCase): + '''Helper class with timed QGuiApplication exec loop''' + + def setUp(self, timeout=100): + '''Sets up this Application. + + timeout - timeout in millisseconds''' + self.app = QGuiApplication.instance() or QGuiApplication([]) + QTimer.singleShot(timeout, self.app.quit) + + def tearDown(self): + '''Delete resources''' + del self.app + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() diff --git a/sources/pyside6/tests/util/helper/usesqapplication.py b/sources/pyside6/tests/util/helper/usesqapplication.py new file mode 100644 index 000000000..f62e320f4 --- /dev/null +++ b/sources/pyside6/tests/util/helper/usesqapplication.py @@ -0,0 +1,43 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Helper classes and functions''' + +import gc +import sys +import unittest + +# This version avoids explicit import in order to adapt to the +# import decision of the main module. +# This should work with every compatible library. +# Replaces the QtGui and QtCore versions as well. + + +class UsesQApplication(unittest.TestCase): + '''Helper class to provide Q(Core|Gui|)Application instances + Just connect or call self.exit_app_cb. When called, will ask + self.app to exit. + ''' + + def setUp(self): + '''Creates the QApplication instance''' + module = sys.modules[sorted(_ for _ in sys.modules + if _.endswith((".QtCore", ".QtGui", ".QtWidgets")))[-1]] + found = module.__name__.rsplit(".")[-1] + cls = getattr(module, {"QtWidgets": "QApplication", + "QtGui": "QGuiApplication", + "QtCore": "QCoreApplication"}[found]) + # Simple way of making instance a singleton + super().setUp() + self.app = cls.instance() or cls([]) + + def tearDown(self): + '''Deletes the reference owned by self''' + del self.app + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + super().tearDown() + + def exit_app_cb(self): + '''Quits the application''' + self.app.exit(0) diff --git a/sources/pyside6/tests/util/httpd.py b/sources/pyside6/tests/util/httpd.py new file mode 100644 index 000000000..4e6be4881 --- /dev/null +++ b/sources/pyside6/tests/util/httpd.py @@ -0,0 +1,153 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import http.server as BaseHTTPServer +import os +import random +import select +import sys +import socketserver as SocketServer +import tempfile +import threading + +sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "util")) + + +class TestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + DATA = b"PySide Server" + allow_reuse_address = True + + def do_GET(self): + self.send_head() + self.wfile.write(TestHandler.DATA) + + def do_HEAD(self): + self.send_head() + + def send_head(self): + self.send_response(200) + self.send_header("Content-type", "text/plain") + self.send_header("Content-Length", str(len(TestHandler.DATA))) + self.end_headers() + + +class TestSecureHandler(BaseHTTPServer.BaseHTTPRequestHandler): + DATA = "PySide" + allow_reuse_address = True + + def do_GET(self): + self.send_head() + self.wfile.write(py3k.b(TestHandler.DATA)) + + def do_HEAD(self): + self.send_head() + + def send_head(self): + try: + handler = self.marshall_handler() + handler.do_request(self) + except: + self.send_response(401) + self.send_header("WWW-Authenticate", "Basic realm='Secure Area'") + self.send_header("Content-type", "text/plain") + self.send_header("Content-Length", str(len(TestHandler.DATA))) + self.end_headers() + +# Workaround for the missing shutdown method in python2.5 + + +class CompatTCPServer(SocketServer.TCPServer): + def __init__(self, server_address, RequestHandlerClass): + SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass) + + self.isPy25 = sys.version_info[0] == 2 and sys.version_info[1] == 5 + if self.isPy25: + self.__is_shut_down = threading.Event() + self.__serving = False + + def serve_forever(self, poll_interval=0.5): + """Handle one request at a time until shutdown. + + Polls for shutdown every poll_interval seconds. Ignores + self.timeout. If you need to do periodic tasks, do them in + another thread. + """ + if self.isPy25: + self.__serving = True + self.__is_shut_down.clear() + while self.__serving: + # XXX: Consider using another file descriptor or + # connecting to the socket to wake this up instead of + # polling. Polling reduces our responsiveness to a + # shutdown request and wastes cpu at all other times. + r, w, e = select.select([self], [], [], poll_interval) + if r: + self.py25_handle_request_noblock() + self.__is_shut_down.set() + else: + SocketServer.TCPServer.serve_forever(self, poll_interval) + + def py25_handle_request_noblock(self): + """Handle one request, without blocking. + + I assume that select.select has returned that the socket is + readable before this function was called, so there should be + no risk of blocking in get_request(). + """ + if self.isPy25: + try: + request, client_address = self.get_request() + except socket.error: + return + if self.verify_request(request, client_address): + try: + self.process_request(request, client_address) + except: + self.handle_error(request, client_address) + self.close_request(request) + + def shutdown(self): + """Stops the serve_forever loop. + + Blocks until the loop has finished. This must be called while + serve_forever() is running in another thread, or it will + deadlock. + """ + if self.isPy25: + self.__serving = False + if not self.__is_shut_down: + self.__is_shut_down.wait() + else: + SocketServer.TCPServer.shutdown(self) + + +class TestServer(threading.Thread): + + def __init__(self, secure=False): + threading.Thread.__init__(self) + + self._port = int(os.getenv("PYSIDE_TESTSERVER_PORT") or 12321) + self.keep_running = True + + if secure: + handle = TestSecureHandler + else: + handle = TestHandler + + while True: + try: + self.httpd = CompatTCPServer(('', self._port), handle) + break + except: + self._port = self._port + random.randint(1, 100) + + def port(self): + return self._port + + def run(self): + self.httpd.serve_forever() + + def shutdown(self): + self.httpd.shutdown() + self.join() + diff --git a/sources/pyside6/tests/util/processtimer.py b/sources/pyside6/tests/util/processtimer.py new file mode 100644 index 000000000..e471cf167 --- /dev/null +++ b/sources/pyside6/tests/util/processtimer.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import time + + +class TimeoutException(Exception): + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return repr(self.msg) + + +class ProcessTimer(object): + '''Timeout function for controlling a subprocess.Popen instance. + + Naive implementation using busy loop, see later other means + of doing this. + ''' + + def __init__(self, proc, timeout): + self.proc = proc + self.timeout = timeout + + def waitfor(self): + time_passed = 0 + while (self.proc.poll() is None and time_passed < self.timeout): + time_passed = time_passed + 1 + time.sleep(1) + + if time_passed >= self.timeout: + raise TimeoutException("Timeout expired, possible deadlock") + + +if __name__ == "__main__": + # simple example + + from subprocess import Popen + + proc = Popen(['sleep', '10']) + t = ProcessTimer(proc, 5) + try: + t.waitfor() + except TimeoutException: + print(f"timeout - PID: {t.proc.pid}") + #TODO: detect SO and kill accordingly + #Linux + os.kill(t.proc.pid, 9) + #Windows (not tested) + #subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True) + print(f"exit code: {t.proc.poll()}") diff --git a/sources/pyside6/tests/util/rename_imports.sh b/sources/pyside6/tests/util/rename_imports.sh new file mode 100755 index 000000000..1ec900cb3 --- /dev/null +++ b/sources/pyside6/tests/util/rename_imports.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +# Rename import statements from .py script to use a specific module name +set -e + +if [ $# -lt 3 ]; then + echo "Usage: $0 <old_name> <new_name> <directories...>" + exit 1 +fi + +old_name=$1; shift +new_name=$1; shift + +find "$@" -name "*.py" -exec sed -ri "s/(import|from) $old_name/\1 $new_name/" '{}' \; diff --git a/sources/pyside6/tests/util/test_processtimer.py b/sources/pyside6/tests/util/test_processtimer.py new file mode 100644 index 000000000..cee6aa14d --- /dev/null +++ b/sources/pyside6/tests/util/test_processtimer.py @@ -0,0 +1,73 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'Tests for processtimer.py' + +import unittest +import os + +from subprocess import Popen, PIPE +from processtimer import TimeoutException, ProcessTimer + + +class TimeoutTest(unittest.TestCase): + + def tearDown(self): + try: + os.kill(self.proc.pid, 9) + except OSError: + pass + + def testRaise(self): + self.proc = Popen(['python2.5', '-c', 'while True: pass'], stdout=PIPE, stderr=PIPE) + timer = ProcessTimer(self.proc, 1) + self.assertRaises(TimeoutException, timer.waitfor) + + +class SimpleTest(unittest.TestCase): + + def tearDown(self): + try: + os.kill(self.proc.pid, 9) + except OSError: + pass + + def testSimple(self): + self.proc = Popen(['python2.5', '-c', '"print"'], stdout=PIPE, stderr=PIPE) + timer = ProcessTimer(self.proc, 10) + timer.waitfor() + + +class TestEchoOutput(unittest.TestCase): + + def tearDown(self): + try: + os.kill(self.proc.pid, 9) + except OSError: + pass + + def testOutput(self): + self.proc = Popen(['python2.5', '-c', 'print 1',], stdout=PIPE, stderr=PIPE) + timer = ProcessTimer(self.proc, 1) + timer.waitfor() + self.assertEqual(self.proc.stdout.read().strip(), '1') + + +class TestRetCode(unittest.TestCase): + + def tearDown(self): + try: + os.kill(self.proc.pid, 9) + except OSError: + pass + + def testSimple(self): + self.proc = Popen(['python2.5', '-c', 'print 1'], stdout=PIPE, stderr=PIPE) + timer = ProcessTimer(self.proc, 10) + timer.waitfor() + + self.assertEqual(self.proc.poll(), 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/util/valgrind-python.supp b/sources/pyside6/tests/util/valgrind-python.supp new file mode 100644 index 000000000..a54b451b3 --- /dev/null +++ b/sources/pyside6/tests/util/valgrind-python.supp @@ -0,0 +1,349 @@ +# +# This is a valgrind suppression file that should be used when using valgrind. +# +# Here's an example of running valgrind: +# +# cd python/dist/src +# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ +# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network +# +# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER +# to use the preferred suppressions with Py_ADDRESS_IN_RANGE. +# +# If you do not want to recompile Python, you can uncomment +# suppressions for PyObject_Free and PyObject_Realloc. +# +# See Misc/README.valgrind for more information. + +# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64) + Memcheck:Value8 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:Py_ADDRESS_IN_RANGE +} + +# +# Leaks (including possible leaks) +# Hmmm, I wonder if this masks some real leaks. I think it does. +# Will need to fix that. +# + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:realloc + fun:_PyObject_GC_Resize + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_New + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_NewVar + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +# +# Non-python specific leaks +# + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:memalign + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Realloc +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Realloc +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Realloc +} + +### +### All the suppressions below are for errors that occur within libraries +### that Python uses. The problems to not appear to be related to Python's +### use of the libraries. +### + +{ + Generic gentoo ld problems + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so +} + +{ + DBM problems, see test_dbm + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_close +} + +{ + DBM problems, see test_dbm + Memcheck:Value8 + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + GDBM problems, see test_gdbm + Memcheck:Param + write(buf) + fun:write + fun:gdbm_open + +} + +{ + ZLIB problems, see test_gzip + Memcheck:Cond + obj:/lib/libz.so.1.2.3 + obj:/lib/libz.so.1.2.3 + fun:deflate +} + +{ + Avoid problems w/readline doing a putenv and leaking on exit + Memcheck:Leak + fun:malloc + fun:xmalloc + fun:sh_set_lines_and_columns + fun:_rl_get_screen_size + fun:_rl_init_terminal_io + obj:/lib/libreadline.so.4.3 + fun:rl_initialize +} + +### +### These occur from somewhere within the SSL, when running +### test_socket_sll. They are too general to leave on by default. +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:memset +###} +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:memset +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:MD5_Update +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:MD5_Update +###} + +# +# All of these problems come from using test_socket_ssl +# +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_bin2bn +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont +} + +{ + from test_socket_ssl + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libcrypto.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_set_key_unchecked +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_encrypt2 +} + +{ + from test_socket_ssl + Memcheck:Cond + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Value4 + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BUF_MEM_grow_clean +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:memcpy + fun:ssl3_read_bytes +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:SHA1_Update +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:SHA1_Update +} + + |