# HG changeset patch # Parent d6ad9d7468f777541bb9f1049aa67fdc4f0b19a7 diff -r d6ad9d7468f7 -r 20a4b36a022c Lib/test/regrtest.py --- a/Lib/test/regrtest.py Sat Jun 08 16:52:29 2013 +0100 +++ b/Lib/test/regrtest.py Sun Jun 09 20:40:13 2013 +0100 @@ -1412,19 +1412,22 @@ repcount = nwarmup + ntracked rc_deltas = [0] * repcount alloc_deltas = [0] * repcount + fd_deltas = [0] * repcount print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr) sys.stderr.flush() for i in range(repcount): indirect_test() - alloc_after, rc_after = dash_R_cleanup(fs, ps, pic, zdc, abcs) + alloc_after, rc_after, fd_after = \ + dash_R_cleanup(fs, ps, pic, zdc, abcs) sys.stderr.write('.') sys.stderr.flush() if i >= nwarmup: rc_deltas[i] = rc_after - rc_before alloc_deltas[i] = alloc_after - alloc_before - alloc_before, rc_before = alloc_after, rc_after + fd_deltas[i] = fd_after - fd_before + alloc_before, rc_before, fd_before = alloc_after, rc_after, fd_after print(file=sys.stderr) # These checkers return False on success, True on failure def check_rc_deltas(deltas): @@ -1437,10 +1440,13 @@ if not set(deltas) <= {1,0,-1}: return True return False + 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_alloc_deltas)]: + (alloc_deltas, 'memory blocks', check_alloc_deltas), + (fd_deltas, 'fds', check_fd_deltas)]: if checker(deltas): msg = '%s leaked %s %s, sum=%s' % ( test, deltas[nwarmup:], item_name, sum(deltas)) @@ -1452,6 +1458,26 @@ failed = True return failed +try: + MAXFD = os.sysconf("SC_OPEN_MAX") +except Exception: + MAXFD = 256 + +def _fdcount(): + """Count the number of open file descriptors""" + import errno + count = 0 + for i in range(MAXFD): + try: + newfd = os.dup(i) + except OSError as e: + if e.errno != errno.EBADF: + raise + else: + count += 1 + os.close(newfd) + return count + def dash_R_cleanup(fs, ps, pic, zdc, abcs): import gc, copyreg import _strptime, linecache @@ -1516,11 +1542,12 @@ else: ctypes._reset_cache() - # Collect cyclic trash and read memory statistics immediately after. + # Collect cyclic trash, read memory and fd statistics immediately after. func1 = sys.getallocatedblocks func2 = sys.gettotalrefcount + func3 = _fdcount gc.collect() - return func1(), func2() + return func1(), func2(), func3() def warm_caches(): # char cache