def test___del__(self): self.assertFalse(self.info_exists("varname")) v = Variable(self.root, "sample string", "varname") self.assertTrue(self.info_exists("varname")) del v support.gc_collect() self.assertFalse(self.info_exists("varname"))
def cleanup_test_droppings(testname, verbose): import shutil # Try to clean up junk commonly left behind. While tests shouldn't leave # any files or directories behind, when a test fails that can be tedious # for it to arrange. The consequences can be especially nasty on Windows, # since if a test leaves a file open, it cannot be deleted by name (while # there's nothing we can do about that here either, we can display the # name of the offending test, which is a real help). for name in (support.TESTFN, "db_home", ): if not os.path.exists(name): continue # work around tests depending on refcounting files, # but this doesn't work with respect to Windows support.gc_collect() if os.path.isdir(name): kind, nuker = "directory", shutil.rmtree elif os.path.isfile(name): kind, nuker = "file", os.unlink else: raise SystemError("os.path says %r exists but is neither " "directory nor file" % name) if verbose: print("%r left behind %s %r" % (testname, kind, name)) try: nuker(name) except Exception as msg: print(("%r left behind %s %r and it couldn't be " "removed: %s" % (testname, kind, name, msg)), file=sys.stderr)
def test_many(self): # mktemp can choose many usable file names (stochastic) extant = list(range(TEST_FILES)) for i in extant: extant[i] = self.do_create(pre="aa") del extant support.gc_collect()
def test__count(self): # Test the _count() function. orig = thread._count() mut = thread.allocate_lock() mut.acquire() started = [] def task(): started.append(None) mut.acquire() mut.release() thread.start_new_thread(task, ()) while not started: time.sleep(0.01) self.assertEqual(thread._count(), orig + 1) # Allow the task to finish. mut.release() # The only reliable way to be sure that the thread ended from the # interpreter's point of view is to wait for the function object to be # destroyed. done = [] wr = weakref.ref(task, lambda _: done.append(None)) del task while not done: time.sleep(0.01) support.gc_collect() self.assertEqual(thread._count(), orig)
def check_future_exception_never_retrieved(self, debug): last_ctx = None def handler(loop, context): nonlocal last_ctx last_ctx = context self.loop.set_debug(debug) self.loop.set_exception_handler(handler) def memory_error(): try: raise MemoryError() except BaseException as exc: return exc exc = memory_error() future = self.create_future() if debug: source_traceback = future._source_traceback future.set_exception(exc) future = None support.gc_collect() test_utils.run_briefly(self.loop) self.assertIsNotNone(last_ctx) self.assertIs(last_ctx['exception'], exc) self.assertEqual(last_ctx['message'], 'Future exception was never retrieved') if debug: tb = last_ctx['source_traceback'] self.assertEqual(tb[-2].name, 'check_future_exception_never_retrieved')
def test_widget_destroy(self): # automatically created variable x = ttk.LabeledScale() var = x._variable._name x.destroy() gc_collect() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var) # manually created variable myvar = tkinter.DoubleVar() name = myvar._name x = ttk.LabeledScale(variable=myvar) x.destroy() if x.tk.wantobjects(): self.assertEqual(x.tk.globalgetvar(name), myvar.get()) else: self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) del myvar gc_collect() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) # checking that the tracing callback is properly removed myvar = tkinter.IntVar() # LabeledScale will start tracing myvar x = ttk.LabeledScale(variable=myvar) x.destroy() # Unless the tracing callback was removed, creating a new # LabeledScale with the same var will cause an error now. This # happens because the variable will be set to (possibly) a new # value which causes the tracing callback to be called and then # it tries calling instance attributes not yet defined. ttk.LabeledScale(variable=myvar) if hasattr(sys, 'last_type'): self.assertNotEqual(sys.last_type, tkinter.TclError)
def test_weakref(self): m = ModuleType("foo") wr = weakref.ref(m) self.assertIs(wr(), m) del m gc_collect() self.assertIs(wr(), None)
def test_resource_warning(self): # Issue #11453 fd = os.open(support.TESTFN, os.O_RDONLY) f = asyncore.file_wrapper(fd) with support.check_warnings(('', ResourceWarning)): f = None support.gc_collect()
def test_tb_logger_exception_unretrieved(self, m_log): fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError("boom")) del fut test_utils.run_briefly(self.loop) support.gc_collect() self.assertTrue(m_log.error.called)
def test_weakref(self): s = array.array(self.typecode, self.example) p = weakref.proxy(s) self.assertEqual(p.tobytes(), s.tobytes()) s = None support.gc_collect() self.assertRaises(ReferenceError, len, p)
def check_future_exception_never_retrieved(self, debug, m_log): self.loop.set_debug(debug) def memory_error(): try: raise MemoryError() except BaseException as exc: return exc exc = memory_error() future = self._new_future(loop=self.loop) future.set_exception(exc) future = None test_utils.run_briefly(self.loop) support.gc_collect() if sys.version_info >= (3, 4): regex = r'^Future exception was never retrieved\n' exc_info = (type(exc), exc, exc.__traceback__) m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) else: regex = r'^Future/Task exception was never retrieved\n' m_log.error.assert_called_once_with(mock.ANY, exc_info=False) message = m_log.error.call_args[0][0] self.assertRegex(message, re.compile(regex, re.DOTALL))
def test_weak_keys(self): # # This exercises d.copy(), d.items(), d[] = v, d[], del d[], # len(d), k in d. # dict, objects = self.make_weak_keyed_dict() for o in objects: self.assertTrue(weakref.getweakrefcount(o) == 1, "wrong number of weak references to %r!" % o) self.assertTrue(o.arg is dict[o], "wrong object returned by weak dict!") items1 = dict.items() items2 = dict.copy().items() self.assertEqual(set(items1), set(items2), "cloning of weak-keyed dictionary did not work!") del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] gc_collect() self.assertTrue(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o gc_collect() self.assertTrue(len(dict) == 0, "deleting the keys did not clear the dictionary") o = Object(42) dict[o] = "What is the meaning of the universe?" self.assertIn(o, dict) self.assertNotIn(34, dict)
def test_weakref(self): f = self.thetype(int, base=16) p = proxy(f) self.assertEqual(f.func, p.func) f = None support.gc_collect() self.assertRaises(ReferenceError, getattr, p, "func")
def testOpenDel(self): self.createTempFile() for i in range(10000): o = BZ2File(self.filename) del o if i % 100 == 0: support.gc_collect()
def test_weakref(self): d = deque('gallahad') p = weakref.proxy(d) self.assertEqual(str(p), str(d)) d = None support.gc_collect() self.assertRaises(ReferenceError, str, p)
def test_trashcan(self): # If this test fails, it will most likely die via segfault. e = root = cET.Element('root') for i in range(200000): e = cET.SubElement(e, 'x') del e del root support.gc_collect()
def test_basic(self): # mktemp can choose usable file names self.do_create() self.do_create(pre="a") self.do_create(suf="b") self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") support.gc_collect()
def test_choose_directory(self): # _mkstemp_inner can create files in a user-selected directory dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write(b"blat") support.gc_collect() finally: os.rmdir(dir)
def tearDown(self): # just in case if we have transport close callbacks if not self.loop.is_closed(): test_utils.run_briefly(self.loop) self.doCleanups() support.gc_collect() super().tearDown()
def test_cycle(self): class myobj(): pass o = myobj() o.s = slice(o) w = weakref.ref(o) o = None support.gc_collect() self.assertIsNone(w())
def test_dont_clear_dict(self): # See issue 7140. def f(): foo = ModuleType("foo") foo.bar = 4 return foo gc_collect() self.assertEqual(f().__dict__["bar"], 4)
def test_func_9(self): async def foo(): pass with self.assertWarnsRegex( RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"): foo() support.gc_collect()
def test_weakref(self): # Check mmap objects are weakrefable mm = mmap.mmap(-1, 16) wr = weakref.ref(mm) self.assertIs(wr(), mm) del mm gc_collect() self.assertIs(wr(), None)
def test_fatal_coro_warning(self): # Issue 27811 async def func(): pass with warnings.catch_warnings(), support.captured_stderr() as stderr: warnings.filterwarnings("error") func() support.gc_collect() self.assertIn("was never awaited", stderr.getvalue())
def test_highly_nested(self): # Issue 25395: crashes during garbage collection OrderedDict = self.OrderedDict obj = None for _ in range(1000): obj = OrderedDict([(None, obj)]) del obj support.gc_collect()
def check_future_exception_never_retrieved(self, debug, m_log): self.loop.set_debug(debug) def memory_error(): try: raise MemoryError() except BaseException as exc: return exc exc = memory_error() future = asyncio.Future(loop=self.loop) if debug: source_traceback = future._source_traceback future.set_exception(exc) future = None test_utils.run_briefly(self.loop) support.gc_collect() if sys.version_info >= (3, 4): if debug: frame = source_traceback[-1] regex = (r'^Future exception was never retrieved\n' r'future: <Future finished exception=MemoryError\(\) created at {filename}:{lineno}>\n' r'source_traceback: Object created at \(most recent call last\):\n' r' File' r'.*\n' r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n' r' future = asyncio\.Future\(loop=self\.loop\)$' ).format(filename=re.escape(frame[0]), lineno=frame[1]) else: regex = (r'^Future exception was never retrieved\n' r'future: <Future finished exception=MemoryError\(\)>$' ) exc_info = (type(exc), exc, exc.__traceback__) m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) else: if debug: frame = source_traceback[-1] regex = (r'^Future/Task exception was never retrieved\n' r'Future/Task created at \(most recent call last\):\n' r' File' r'.*\n' r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n' r' future = asyncio\.Future\(loop=self\.loop\)\n' r'Traceback \(most recent call last\):\n' r'.*\n' r'MemoryError$' ).format(filename=re.escape(frame[0]), lineno=frame[1]) else: regex = (r'^Future/Task exception was never retrieved\n' r'Traceback \(most recent call last\):\n' r'.*\n' r'MemoryError$' ) m_log.error.assert_called_once_with(mock.ANY, exc_info=False) message = m_log.error.call_args[0][0] self.assertRegex(message, re.compile(regex, re.DOTALL))
def test_iterparse_leaks(self): # Test reference leaks in TreeBuilder (issue #35502). # The test is written to be executed in the hunting reference leaks # mode. XML = '<a></a></b>' parser = cET.iterparse(io.StringIO(XML)) next(parser) del parser support.gc_collect()
def test_xmlpullparser_leaks(self): # Test reference leaks in TreeBuilder (issue #35502). # The test is written to be executed in the hunting reference leaks # mode. XML = '<a></a></b>' parser = cET.XMLPullParser() parser.feed(XML) del parser support.gc_collect()
def test_contains(self): for c in self.letters: self.assertEqual(c in self.s, c in self.d) # 1 is not weakref'able, but that TypeError is caught by __contains__ self.assertNotIn(1, self.s) self.assertIn(self.obj, self.fs) del self.obj support.gc_collect() self.assertNotIn(ustr('F'), self.fs)
def testWeakRefs(self): # verify weak references p = proxy(self.f) p.write(bytes(list(range(10)))) self.assertEqual(self.f.tell(), p.tell()) self.f.close() self.f = None gc_collect() self.assertRaises(ReferenceError, getattr, p, 'tell')
def cleanup_test_droppings(test_name, verbose): # First kill any dangling references to open files etc. # This can also issue some ResourceWarnings which would otherwise get # triggered during the following test run, and possibly produce failures. support.gc_collect() # Try to clean up junk commonly left behind. While tests shouldn't leave # any files or directories behind, when a test fails that can be tedious # for it to arrange. The consequences can be especially nasty on Windows, # since if a test leaves a file open, it cannot be deleted by name (while # there's nothing we can do about that here either, we can display the # name of the offending test, which is a real help). for name in (support.TESTFN, ): if not os.path.exists(name): continue if os.path.isdir(name): import shutil kind, nuker = "directory", shutil.rmtree elif os.path.isfile(name): kind, nuker = "file", os.unlink else: raise RuntimeError(f"os.path says {name!r} exists but is neither " f"directory nor file") if verbose: print_warning(f"{test_name} left behind {kind} {name!r}") support.environment_altered = True try: import stat # fix possible permissions problems that might prevent cleanup os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) nuker(name) except Exception as exc: print_warning(f"{test_name} left behind {kind} {name!r} " f"and it couldn't be removed: {exc}")
def test_pass_by_value_finalizer(self): # bpo-37140: Similar to test_pass_by_value(), but the Python structure # has a finalizer (__del__() method): the finalizer must only be called # once. finalizer_calls = [] class Test(Structure): _fields_ = [ ('first', c_ulong), ('second', c_ulong), ('third', c_ulong), ] def __del__(self): finalizer_calls.append("called") s = Test(1, 2, 3) # Test the StructUnionType_paramfunc() code path which copies the # structure: if the stucture is larger than sizeof(void*). self.assertGreater(sizeof(s), sizeof(c_void_p)) dll = CDLL(_ctypes_test.__file__) func = dll._testfunc_large_struct_update_value func.argtypes = (Test,) func.restype = None func(s) # bpo-37140: Passing the structure by refrence must not call # its finalizer! self.assertEqual(finalizer_calls, []) self.assertEqual(s.first, 1) self.assertEqual(s.second, 2) self.assertEqual(s.third, 3) # The finalizer must be called exactly once s = None support.gc_collect() self.assertEqual(finalizer_calls, ["called"])
def _check_generator_cleanup_exc_state(self, testfunc): # Issue #12791: exception state is cleaned up as soon as a generator # is closed (reference cycles are broken). class MyException(Exception): def __init__(self, obj): self.obj = obj class MyObj: pass def raising_gen(): try: raise MyException(obj) except MyException: yield obj = MyObj() wr = weakref.ref(obj) g = raising_gen() next(g) testfunc(g) g = obj = None gc_collect() obj = wr() self.assertIs(obj, None)
def test_getbuffer(self): memio = self.ioclass(b"1234567890") buf = memio.getbuffer() self.assertEqual(bytes(buf), b"1234567890") memio.seek(5) buf = memio.getbuffer() self.assertEqual(bytes(buf), b"1234567890") # Trying to change the size of the BytesIO while a buffer is exported # raises a BufferError. self.assertRaises(BufferError, memio.write, b'x' * 100) self.assertRaises(BufferError, memio.truncate) self.assertRaises(BufferError, memio.close) self.assertFalse(memio.closed) # Mutating the buffer updates the BytesIO buf[3:6] = b"abc" self.assertEqual(bytes(buf), b"123abc7890") self.assertEqual(memio.getvalue(), b"123abc7890") # After the buffer gets released, we can resize and close the BytesIO # again del buf support.gc_collect() memio.truncate() memio.close() self.assertRaises(ValueError, memio.getbuffer)
def cleanup_test_droppings(testname, verbose): import shutil # Try to clean up junk commonly left behind. While tests shouldn't leave # any files or directories behind, when a test fails that can be tedious # for it to arrange. The consequences can be especially nasty on Windows, # since if a test leaves a file open, it cannot be deleted by name (while # there's nothing we can do about that here either, we can display the # name of the offending test, which is a real help). for name in ( support.TESTFN, "db_home", ): if not os.path.exists(name): continue # work around tests depending on refcounting files, # but this doesn't work with respect to Windows support.gc_collect() if os.path.isdir(name): kind, nuker = "directory", shutil.rmtree elif os.path.isfile(name): kind, nuker = "file", os.unlink else: raise SystemError("os.path says %r exists but is neither " "directory nor file" % name) if verbose: print("%r left behind %s %r" % (testname, kind, name)) try: nuker(name) except Exception as msg: print(("%r left behind %s %r and it couldn't be " "removed: %s" % (testname, kind, name, msg)), file=sys.stderr)
def test_deepcopy_weakvaluedict(self): class C(object): def __init__(self, i): self.i = i a, b, c, d = [C(i) for i in range(4)] u = weakref.WeakValueDictionary() u[a] = b u[c] = d # Keys are copied, values aren't v = copy.deepcopy(u) self.assertNotEqual(v, u) self.assertEqual(len(v), 2) (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i) self.assertIsNot(x, a) self.assertEqual(x.i, a.i) self.assertIs(y, b) self.assertIsNot(z, c) self.assertEqual(z.i, c.i) self.assertIs(t, d) del x, y, z, t del d support.gc_collect() self.assertEqual(len(v), 1)
def test_class_to_test_weakness(self): # regrtest for bug 1522, adapted from test code submitted by Matt Brinkley # work around the fact that we can't look at PyType directly # by using this helper function that reflects on PyType (and # demonstrates here that it's the same as the builtin function # `type`!) class_to_type_map = getField(type, 'class_to_type').get(None) def create_proxies(): pi = PythonInterpreter() pi.exec(""" from java.lang import Comparable class Dog(Comparable): def compareTo(self, o): return 0 def bark(self): return 'woof woof' Dog().bark() """) # get to steady state first, then verify we don't create new proxies for i in xrange(2): create_proxies() # Ensure the reaper thread can run and clear out weak refs, so # use this supporting function support.gc_collect() # Given that taking the len (or size()) of Guava weak maps is # eventually consistent, we should instead take a len of its # keys. start_size = len(list(class_to_type_map)) for i in xrange(5): create_proxies() support.gc_collect() self.assertEqual(start_size, len(list(class_to_type_map)))
def test_len(self): self.assertEqual(len(self.s), len(self.d)) self.assertEqual(len(self.fs), 1) del self.obj support.gc_collect() self.assertEqual(len(self.fs), 0)
def test_len(self): self.assertEqual(len(self.s), len(self.d)) self.assertEqual(len(self.fs), 1) del self.obj support.gc_collect() # For PyPy or other GCs. self.assertEqual(len(self.fs), 0)
def setUp(self): support.gc_collect() if os.path.exists(support.TESTFN): os.unlink(support.TESTFN)
def clear_caches(): # Clear the warnings registry, so they can be displayed again for mod in sys.modules.values(): if hasattr(mod, '__warningregistry__'): del mod.__warningregistry__ # Flush standard output, so that buffered data is sent to the OS and # associated Python objects are reclaimed. for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): if stream is not None: stream.flush() # Clear assorted module caches. # Don't worry about resetting the cache if the module is not loaded try: distutils_dir_util = sys.modules['distutils.dir_util'] except KeyError: pass else: distutils_dir_util._path_created.clear() try: re = sys.modules['re'] except KeyError: pass else: re.purge() try: _strptime = sys.modules['_strptime'] except KeyError: pass else: _strptime._regex_cache.clear() try: urllib_parse = sys.modules['urllib.parse'] except KeyError: pass else: urllib_parse.clear_cache() try: urllib_request = sys.modules['urllib.request'] except KeyError: pass else: urllib_request.urlcleanup() try: linecache = sys.modules['linecache'] except KeyError: pass else: linecache.clearcache() try: mimetypes = sys.modules['mimetypes'] except KeyError: pass else: mimetypes._default_mime_types() try: filecmp = sys.modules['filecmp'] except KeyError: pass else: filecmp._cache.clear() try: struct = sys.modules['struct'] except KeyError: pass else: struct._clearcache() try: doctest = sys.modules['doctest'] except KeyError: pass else: doctest.master = None try: ctypes = sys.modules['ctypes'] except KeyError: pass else: ctypes._reset_cache() try: typing = sys.modules['typing'] except KeyError: pass else: for f in typing._cleanups: f() support.gc_collect()
def test_gc_collect(self): support.gc_collect()
def testExceptionCleanupState(self): # Make sure exception state is cleaned up as soon as the except # block is left. See #2507 class MyException(Exception): def __init__(self, obj): self.obj = obj class MyObj: pass def inner_raising_func(): # Create some references in exception value and traceback local_ref = obj raise MyException(obj) # Qualified "except" with "as" obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException as e: pass obj = None obj = wr() self.assertIsNone(obj) # Qualified "except" without "as" obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException: pass obj = None obj = wr() self.assertIsNone(obj) # Bare "except" obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except: pass obj = None obj = wr() self.assertIsNone(obj) # "except" with premature block leave obj = MyObj() wr = weakref.ref(obj) for i in [0]: try: inner_raising_func() except: break obj = None obj = wr() self.assertIsNone(obj) # "except" block raising another exception obj = MyObj() wr = weakref.ref(obj) try: try: inner_raising_func() except: raise KeyError except KeyError as e: # We want to test that the except block above got rid of # the exception raised in inner_raising_func(), but it # also ends up in the __context__ of the KeyError, so we # must clear the latter manually for our test to succeed. e.__context__ = None obj = None obj = wr() # guarantee no ref cycles on CPython (don't gc_collect) if check_impl_detail(cpython=False): gc_collect() self.assertIsNone(obj) # Some complicated construct obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException: try: try: raise finally: raise except MyException: pass obj = None if check_impl_detail(cpython=False): gc_collect() obj = wr() self.assertIsNone(obj) # Inside an exception-silencing "with" block class Context: def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): return True obj = MyObj() wr = weakref.ref(obj) with Context(): inner_raising_func() obj = None if check_impl_detail(cpython=False): gc_collect() obj = wr() self.assertIsNone(obj)
def dash_R(ns, test_name, test_func): """Run a test multiple times, looking for reference leaks. Returns: False if the test didn't leak references; True if we detected refleaks. """ # This code is hackish and inelegant, but it seems to do the job. import copyreg import collections.abc if not hasattr(sys, 'gettotalrefcount'): raise Exception("Tracking reference leaks requires a debug build " "of Python") # Avoid false positives due to various caches # filling slowly with random data: warm_caches() # Save current values for dash_R_cleanup() to restore. fs = warnings.filters[:] ps = copyreg.dispatch_table.copy() pic = sys.path_importer_cache.copy() try: import zipimport except ImportError: zdc = None # Run unmodified on platforms without zipimport support else: zdc = zipimport._zip_directory_cache.copy() abcs = {} for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: if not isabstract(abc): continue for obj in abc.__subclasses__() + [abc]: abcs[obj] = _get_dump(obj)[0] # bpo-31217: Integer pool to get a single integer object for the same # value. The pool is used to prevent false alarm when checking for memory # block leaks. Fill the pool with values in -1000..1000 which are the most # common (reference, memory block, file descriptor) differences. int_pool = {value: value for value in range(-1000, 1000)} def get_pooled_int(value): return int_pool.setdefault(value, value) nwarmup, ntracked, fname = ns.huntrleaks fname = os.path.join(os_helper.SAVEDCWD, fname) repcount = nwarmup + ntracked # Pre-allocate to ensure that the loop doesn't allocate anything new rep_range = list(range(repcount)) rc_deltas = [0] * repcount alloc_deltas = [0] * repcount fd_deltas = [0] * repcount getallocatedblocks = sys.getallocatedblocks gettotalrefcount = sys.gettotalrefcount _getquickenedcount = sys._getquickenedcount fd_count = os_helper.fd_count # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = 0 if not ns.quiet: print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890" * (repcount // 10 + 1))[:repcount], file=sys.stderr, flush=True) dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() for i in rep_range: test_func() dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() # Read memory statistics immediately after the garbage collection alloc_after = getallocatedblocks() - _getquickenedcount() rc_after = gettotalrefcount() fd_after = fd_count() if not ns.quiet: print('.', end='', file=sys.stderr, flush=True) rc_deltas[i] = get_pooled_int(rc_after - rc_before) alloc_deltas[i] = get_pooled_int(alloc_after - alloc_before) fd_deltas[i] = get_pooled_int(fd_after - fd_before) alloc_before = alloc_after rc_before = rc_after fd_before = fd_after if not ns.quiet: print(file=sys.stderr) # These checkers return False on success, True on failure def check_rc_deltas(deltas): # Checker for reference counters and memory blocks. # # bpo-30776: Try to ignore false positives: # # [3, 0, 0] # [0, 1, 0] # [8, -8, 1] # # Expected leaks: # # [5, 5, 6] # [10, 1, 1] return all(delta >= 1 for delta in deltas) def check_fd_deltas(deltas): return any(deltas) failed = False for deltas, item_name, checker in [ (rc_deltas, 'references', check_rc_deltas), (alloc_deltas, 'memory blocks', check_rc_deltas), (fd_deltas, 'file descriptors', check_fd_deltas) ]: # ignore warmup runs deltas = deltas[nwarmup:] if checker(deltas): msg = '%s leaked %s %s, sum=%s' % (test_name, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr, flush=True) with open(fname, "a") as refrep: print(msg, file=refrep) refrep.flush() failed = True return failed
def silence_coro_gc(): with warnings.catch_warnings(): warnings.simplefilter("ignore") yield support.gc_collect()
def test_create_connection_memory_leak(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE server_context = test_utils.simple_server_sslcontext() client_context = test_utils.simple_client_sslcontext() def serve(sock): sock.settimeout(self.TIMEOUT) sock.start_tls(server_context, server_side=True) sock.sendall(b'O') data = sock.recv_all(len(HELLO_MSG)) self.assertEqual(len(data), len(HELLO_MSG)) sock.shutdown(socket.SHUT_RDWR) sock.close() class ClientProto(asyncio.Protocol): def __init__(self, on_data, on_eof): self.on_data = on_data self.on_eof = on_eof self.con_made_cnt = 0 def connection_made(proto, tr): # XXX: We assume user stores the transport in protocol proto.tr = tr proto.con_made_cnt += 1 # Ensure connection_made gets called only once. self.assertEqual(proto.con_made_cnt, 1) def data_received(self, data): self.on_data.set_result(data) def eof_received(self): self.on_eof.set_result(True) async def client(addr): await asyncio.sleep(0.5) on_data = self.loop.create_future() on_eof = self.loop.create_future() tr, proto = await self.loop.create_connection( lambda: ClientProto(on_data, on_eof), *addr, ssl=client_context) self.assertEqual(await on_data, b'O') tr.write(HELLO_MSG) await on_eof tr.close() with self.tcp_server(serve, timeout=self.TIMEOUT) as srv: self.loop.run_until_complete( asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) # No garbage is left for SSL client from loop.create_connection, even # if user stores the SSLTransport in corresponding protocol instance client_context = weakref.ref(client_context) support.gc_collect() self.assertIsNone(client_context())
def test_start_tls_client_reg_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE server_context = test_utils.simple_server_sslcontext() client_context = test_utils.simple_client_sslcontext() def serve(sock): sock.settimeout(self.TIMEOUT) data = sock.recv_all(len(HELLO_MSG)) self.assertEqual(len(data), len(HELLO_MSG)) sock.start_tls(server_context, server_side=True) sock.sendall(b'O') data = sock.recv_all(len(HELLO_MSG)) self.assertEqual(len(data), len(HELLO_MSG)) sock.shutdown(socket.SHUT_RDWR) sock.close() class ClientProto(asyncio.Protocol): def __init__(self, on_data, on_eof): self.on_data = on_data self.on_eof = on_eof self.con_made_cnt = 0 def connection_made(proto, tr): proto.con_made_cnt += 1 # Ensure connection_made gets called only once. self.assertEqual(proto.con_made_cnt, 1) def data_received(self, data): self.on_data.set_result(data) def eof_received(self): self.on_eof.set_result(True) async def client(addr): await asyncio.sleep(0.5) on_data = self.loop.create_future() on_eof = self.loop.create_future() tr, proto = await self.loop.create_connection( lambda: ClientProto(on_data, on_eof), *addr) tr.write(HELLO_MSG) new_tr = await self.loop.start_tls(tr, proto, client_context) self.assertEqual(await on_data, b'O') new_tr.write(HELLO_MSG) await on_eof new_tr.close() with self.tcp_server(serve, timeout=self.TIMEOUT) as srv: self.loop.run_until_complete( asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) # No garbage is left if SSL is closed uncleanly client_context = weakref.ref(client_context) support.gc_collect() self.assertIsNone(client_context())
def testExceptionCleanupState(self): class MyException(Exception): def __init__(self, obj): self.obj = obj class MyObj: pass def inner_raising_func(): local_ref = obj raise MyException(obj) obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException as e: pass obj = None obj = wr() self.assertTrue(obj is None, '%s' % obj) obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException: pass obj = None obj = wr() self.assertTrue(obj is None, '%s' % obj) obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except: pass obj = None obj = wr() self.assertTrue(obj is None, '%s' % obj) obj = MyObj() wr = weakref.ref(obj) for i in [0]: try: inner_raising_func() except: break obj = None obj = wr() self.assertTrue(obj is None, '%s' % obj) obj = MyObj() wr = weakref.ref(obj) try: try: inner_raising_func() except: raise KeyError except KeyError as e: e.__context__ = None obj = None obj = wr() if check_impl_detail(cpython=False): gc_collect() self.assertTrue(obj is None, '%s' % obj) obj = MyObj() wr = weakref.ref(obj) try: inner_raising_func() except MyException: try: try: raise finally: raise except MyException: pass obj = None if check_impl_detail(cpython=False): gc_collect() obj = wr() self.assertTrue(obj is None, '%s' % obj) class Context: def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): return True obj = MyObj() wr = weakref.ref(obj) with Context(): inner_raising_func() obj = None if check_impl_detail(cpython=False): gc_collect() obj = wr() self.assertTrue(obj is None, '%s' % obj)
def tearDown(self): support.gc_collect() if os.path.isfile(self.filename): os.unlink(self.filename)
def post_test_cleanup(): support.gc_collect() support.reap_children()
def test_all_locks(self): support.gc_collect() self.assertEqual(0, len(self.bootstrap._module_locks), self.bootstrap._module_locks)
def tearDown(self): # Ensure that IsolatedAsyncioTestCase instances are destroyed before # starting a new event loop support.gc_collect()
def check_future_exception_never_retrieved(self, debug, m_log): self.loop.set_debug(debug) def memory_error(): try: raise MemoryError() except BaseException as exc: return exc exc = memory_error() future = asyncio.Future(loop=self.loop) if debug: source_traceback = future._source_traceback future.set_exception(exc) future = None test_utils.run_briefly(self.loop) support.gc_collect() if sys.version_info >= (3, 4): if debug: frame = source_traceback[-1] regex = (r'^Future exception was never retrieved\n' r'future: <Future finished exception=MemoryError\(\) ' r'created at {filename}:{lineno}>\n' r'source_traceback: Object ' r'created at \(most recent call last\):\n' r' File' r'.*\n' r' File "{filename}", line {lineno}, ' r'in check_future_exception_never_retrieved\n' r' future = asyncio\.Future\(loop=self\.loop\)$' ).format(filename=re.escape(frame[0]), lineno=frame[1]) else: regex = (r'^Future exception was never retrieved\n' r'future: ' r'<Future finished exception=MemoryError\(\)>$') exc_info = (type(exc), exc, exc.__traceback__) m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) else: if debug: frame = source_traceback[-1] regex = (r'^Future/Task exception was never retrieved\n' r'Future/Task created at \(most recent call last\):\n' r' File' r'.*\n' r' File "{filename}", line {lineno}, ' r'in check_future_exception_never_retrieved\n' r' future = asyncio\.Future\(loop=self\.loop\)\n' r'Traceback \(most recent call last\):\n' r'.*\n' r'MemoryError$').format(filename=re.escape(frame[0]), lineno=frame[1]) else: regex = (r'^Future/Task exception was never retrieved\n' r'Traceback \(most recent call last\):\n' r'.*\n' r'MemoryError$') m_log.error.assert_called_once_with(mock.ANY, exc_info=False) message = m_log.error.call_args[0][0] self.assertRegex(message, re.compile(regex, re.DOTALL))
def _collect_if_necessary(self): if sys.implementation.name != 'cpython': support.gc_collect()