33any memory leaks or error handling issues.
44"""
55import argparse
6+ import curses
67import logging
78import os
89import random
910import resource
10- import sys
1111import time
12+ import tracemalloc
1213import unittest
1314
1415import tests .test_dict_encoding as test_dict_encoding
1516import tests .test_file_format as test_file_format
1617import tests .test_haplotype_matching as test_haplotype_matching
1718import tests .test_highlevel as test_highlevel
1819import tests .test_lowlevel as test_lowlevel
20+ import tests .test_metadata as test_metadata
1921import tests .test_stats as test_stats
2022import tests .test_tables as test_tables
2123import tests .test_threads as test_threads
2426import tests .test_vcf as test_vcf
2527
2628
27- def main ():
29+ def main (stdscr ):
2830 modules = {
2931 "highlevel" : test_highlevel ,
3032 "lowlevel" : test_lowlevel ,
@@ -37,6 +39,7 @@ def main():
3739 "topology" : test_topology ,
3840 "dict_encoding" : test_dict_encoding ,
3941 "haplotype_matching" : test_haplotype_matching ,
42+ "metadata" : test_metadata ,
4043 }
4144 parser = argparse .ArgumentParser (
4245 description = "Run tests in a loop to stress low-level interface"
@@ -55,13 +58,14 @@ def main():
5558 # Need to do this to silence the errors from the file_format tests.
5659 logging .basicConfig (level = logging .ERROR )
5760
58- print ("iter\t tests\t err\t fail\t skip\t RSS\t min\t max\t max@iter" )
5961 max_rss = 0
6062 max_rss_iter = 0
6163 min_rss = 1e100
6264 iteration = 0
6365 last_print = time .time ()
6466 devnull = open (os .devnull , "w" )
67+ tracemalloc .start ()
68+ memory_start = None
6569 while True :
6670 # We don't want any random variation in the amount of memory
6771 # used from test-to-test.
@@ -71,7 +75,10 @@ def main():
7175 for mod in test_modules [1 :]:
7276 suite .addTests (testloader .loadTestsFromModule (mod ))
7377 runner = unittest .TextTestRunner (verbosity = 0 , stream = devnull )
78+ if memory_start is None :
79+ memory_start = tracemalloc .take_snapshot ()
7480 result = runner .run (suite )
81+ memory_current = tracemalloc .take_snapshot ()
7582 rusage = resource .getrusage (resource .RUSAGE_SELF )
7683 if max_rss < rusage .ru_maxrss :
7784 max_rss = rusage .ru_maxrss
@@ -81,24 +88,46 @@ def main():
8188
8289 # We don't want to flood stdout, so we rate-limit to 1 per second.
8390 if time .time () - last_print > 1 :
84- print (
85- iteration ,
86- result .testsRun ,
87- len (result .failures ),
88- len (result .errors ),
89- len (result .skipped ),
90- rusage .ru_maxrss ,
91- min_rss ,
92- max_rss ,
93- max_rss_iter ,
94- sep = "\t " ,
95- end = "\r " ,
91+ stdscr .clear ()
92+ stdscr .addstr (0 , 0 , "iter\t tests\t err\t fail\t skip\t RSS\t min\t max\t max@iter" )
93+ stdscr .addstr (
94+ 1 ,
95+ 0 ,
96+ "\t " .join (
97+ map (
98+ str ,
99+ [
100+ iteration ,
101+ result .testsRun ,
102+ len (result .failures ),
103+ len (result .errors ),
104+ len (result .skipped ),
105+ rusage .ru_maxrss ,
106+ min_rss ,
107+ max_rss ,
108+ max_rss_iter ,
109+ ],
110+ )
111+ ),
96112 )
113+ stats = memory_current .compare_to (memory_start , "traceback" )
114+ rows , cols = stdscr .getmaxyx ()
115+ for i , stat in enumerate (stats [: rows - 3 ], 1 ):
116+ stdscr .addstr (i + 2 , 0 , str (stat ))
97117 last_print = time .time ()
98- sys . stdout . flush ()
118+ stdscr . refresh ()
99119
100120 iteration += 1
101121
102122
103123if __name__ == "__main__" :
104- main ()
124+ stdscr = curses .initscr ()
125+ curses .noecho ()
126+ curses .cbreak ()
127+
128+ try :
129+ main (stdscr )
130+ finally :
131+ curses .echo ()
132+ curses .nocbreak ()
133+ curses .endwin ()
0 commit comments