@@ -72,7 +72,45 @@ def _outcome(kind, test, detail):
7272 for t , tb in result .expectedFailures ]
7373outcomes += [_outcome ('skipped' , t , reason ) for t , reason in result .skipped ]
7474
75- payload = {'outcomes' : outcomes , 'durations' : result .id_durations }
75+ def _usage ():
76+ """What this process used: peak resident set size in bytes, and the
77+ number of major page faults it took, either of which can be None.
78+
79+ A major page fault is served from disk, so a non-zero count means swapping.
80+
81+ The modules are imported here, after the test has run, so that the test
82+ does not see them.
83+ """
84+ try :
85+ import resource
86+ except ImportError :
87+ pass
88+ else :
89+ usage = resource .getrusage (resource .RUSAGE_SELF )
90+ # Solaris and illumos leave these fields at 0, which no live process
91+ # has, so treat it as "not supported".
92+ if not usage .ru_maxrss :
93+ return {'maxrss' : None , 'majflt' : None }
94+ # ru_maxrss is in bytes on macOS, in kilobytes on Linux and the BSDs.
95+ maxrss = usage .ru_maxrss
96+ return {'maxrss' : maxrss if sys .platform == 'darwin' else maxrss * 1024 ,
97+ 'majflt' : usage .ru_majflt }
98+ try :
99+ import os
100+ import _winapi
101+ handle = _winapi .OpenProcess (
102+ _winapi .PROCESS_QUERY_LIMITED_INFORMATION , False , os .getpid ())
103+ except (ImportError , OSError ):
104+ return {'maxrss' : None , 'majflt' : None }
105+ try :
106+ info = _winapi .GetProcessMemoryInfo (handle )
107+ finally :
108+ _winapi .CloseHandle (handle )
109+ # PageFaultCount counts all faults, not only the ones served from disk.
110+ return {'maxrss' : info ['PeakWorkingSetSize' ], 'majflt' : None }
111+
112+
113+ payload = {'outcomes' : outcomes , 'durations' : result .id_durations , ** _usage ()}
76114with open (outfile , 'wb' ) as f :
77115 marshal .dump (payload , f )
78116
0 commit comments