bpo-30263: regrtest: log system load (#1452)

* bpo-30263: regrtest: log system load

* regrtest: log the number of CPUs

Log the number of CPUs in the header. --verbose now imply --header.
diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py
index d621f5f..8260b09 100644
--- a/Lib/test/libregrtest/cmdline.py
+++ b/Lib/test/libregrtest/cmdline.py
@@ -343,5 +343,7 @@
                     ns.use_resources.append(r)
     if ns.random_seed is not None:
         ns.randomize = True
+    if ns.verbose:
+        ns.header = True
 
     return ns
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index de1f4f9..2cfbdd1 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -120,18 +120,22 @@
     def display_progress(self, test_index, test):
         if self.ns.quiet:
             return
+
+        # "[ 51/405/1] test_tcl passed"
+        line = f"{test_index:{self.test_count_width}}{self.test_count}"
         if self.bad and not self.ns.pgo:
-            fmt = "{time} [{test_index:{count_width}}{test_count}/{nbad}] {test_name}"
-        else:
-            fmt = "{time} [{test_index:{count_width}}{test_count}] {test_name}"
+            line = f"{line}/{len(self.bad)}"
+        line = f"[{line}] {test}"
+
+        # add the system load prefix: "load avg: 1.80 "
+        if hasattr(os, 'getloadavg'):
+            load_avg_1min = os.getloadavg()[0]
+            line = f"load avg: {load_avg_1min:.2f} {line}"
+
+        # add the timestamp prefix:  "0:01:05 "
         test_time = time.monotonic() - self.start_time
         test_time = datetime.timedelta(seconds=int(test_time))
-        line = fmt.format(count_width=self.test_count_width,
-                          test_index=test_index,
-                          test_count=self.test_count,
-                          nbad=len(self.bad),
-                          test_name=test,
-                          time=test_time)
+        line = f"{test_time} {line}"
         print(line, flush=True)
 
     def parse_args(self, kwargs):
@@ -376,23 +380,28 @@
                 if self.bad:
                     return
 
+    def display_header(self):
+        # Print basic platform information
+        print("==", platform.python_implementation(), *sys.version.split())
+        print("==", platform.platform(aliased=True),
+                      "%s-endian" % sys.byteorder)
+        print("== hash algorithm:", sys.hash_info.algorithm,
+              "64bit" if sys.maxsize > 2**32 else "32bit")
+        print("== cwd:", os.getcwd())
+        cpu_count = os.cpu_count()
+        if cpu_count:
+            print("== CPU count:", cpu_count)
+        print("== encodings: locale=%s, FS=%s"
+              % (locale.getpreferredencoding(False),
+                 sys.getfilesystemencoding()))
+        print("Testing with flags:", sys.flags)
+
     def run_tests(self):
         # For a partial run, we do not need to clutter the output.
-        if (self.ns.verbose
-            or self.ns.header
-            or not (self.ns.pgo or self.ns.quiet or self.ns.single
-                    or self.tests or self.ns.args)):
-            # Print basic platform information
-            print("==", platform.python_implementation(), *sys.version.split())
-            print("==  ", platform.platform(aliased=True),
-                          "%s-endian" % sys.byteorder)
-            print("==  ", "hash algorithm:", sys.hash_info.algorithm,
-                  "64bit" if sys.maxsize > 2**32 else "32bit")
-            print("==  cwd:", os.getcwd())
-            print("==  encodings: locale=%s, FS=%s"
-                  % (locale.getpreferredencoding(False),
-                     sys.getfilesystemencoding()))
-            print("Testing with flags:", sys.flags)
+        if (self.ns.header
+            or not(self.ns.pgo or self.ns.quiet or self.ns.single
+                   or self.tests or self.ns.args)):
+            self.display_header()
 
         if self.ns.randomize:
             print("Using random seed", self.ns.random_seed)
diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
index 0bd6298..d349260 100644
--- a/Lib/test/test_regrtest.py
+++ b/Lib/test/test_regrtest.py
@@ -118,6 +118,9 @@
         ns = libregrtest._parse_args(['--header'])
         self.assertTrue(ns.header)
 
+        ns = libregrtest._parse_args(['--verbose'])
+        self.assertTrue(ns.header)
+
     def test_randomize(self):
         for opt in '-r', '--randomize':
             with self.subTest(opt=opt):
@@ -354,7 +357,7 @@
         self.assertRegex(output, regex)
 
     def parse_executed_tests(self, output):
-        regex = (r'^[0-9]+:[0-9]+:[0-9]+ \[ *[0-9]+(?:/ *[0-9]+)*\] (%s)'
+        regex = (r'^[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)'
                  % self.TESTNAME_REGEX)
         parser = re.finditer(regex, output, re.MULTILINE)
         return list(match.group(1) for match in parser)