summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2023-04-27 13:52:46 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-27 04:23:54 +0000
commitafc718c315bf713c6a3d79ebcfac23a35b36f1a5 (patch)
treeaacb147ba7ced5bba97c43d8fac06d1f86cb47f6
parentc974b94d01f529df754554605e5ea3e4d675aaf4 (diff)
downloadmongo-afc718c315bf713c6a3d79ebcfac23a35b36f1a5.tar.gz
Import wiredtiger: a7dc285de9c56a5d66522e8887543b9b4c157f09 from branch mongodb-6.0
ref: 282fe2bab6..a7dc285de9 for: 6.0.6 WT-8932 Call wait on forked child from Python tests and add extra debugging for PIDs
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/PKG-INFO (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/PKG-INFO)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/README4
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/PKG-INFO (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/PKG-INFO)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/SOURCES.txt (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/SOURCES.txt)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/dependency_links.txt (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/dependency_links.txt)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/requires.txt (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/requires.txt)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/top_level.txt (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/top_level.txt)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.py (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.py)32
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.cfg (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.cfg)0
-rw-r--r--src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.py (renamed from src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.py)0
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/wttest.py61
12 files changed, 88 insertions, 11 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 39ed9e47ff2..5bde51e352a 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-6.0",
- "commit": "282fe2bab684f89ea92edf111461ccbe1b469375"
+ "commit": "a7dc285de9c56a5d66522e8887543b9b4c157f09"
}
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/PKG-INFO b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/PKG-INFO
index edb06bf7a42..edb06bf7a42 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/PKG-INFO
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/PKG-INFO
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/README b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/README
new file mode 100644
index 00000000000..e9d53be96d1
--- /dev/null
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/README
@@ -0,0 +1,4 @@
+We have modified concurrencytest.py from the original concurrencytest-0.1.2 to wait for the child processes
+preventing defunct processes and to prefix output with the running PID for debuggability.o
+
+Future changes such as updating concurrencytest must take this into account.
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/PKG-INFO b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/PKG-INFO
index edb06bf7a42..edb06bf7a42 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/PKG-INFO
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/PKG-INFO
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/SOURCES.txt b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/SOURCES.txt
index bf9f692ad1f..bf9f692ad1f 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/SOURCES.txt
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/SOURCES.txt
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/dependency_links.txt b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/dependency_links.txt
index 8b137891791..8b137891791 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/dependency_links.txt
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/dependency_links.txt
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/requires.txt b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/requires.txt
index 537ebcbac33..537ebcbac33 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/requires.txt
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/requires.txt
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/top_level.txt b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/top_level.txt
index cfc96e6db71..cfc96e6db71 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.egg-info/top_level.txt
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.egg-info/top_level.txt
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.py b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.py
index b3cb52d48d3..f9049ce8518 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/concurrencytest.py
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/concurrencytest.py
@@ -23,7 +23,9 @@ Unix only.
import os
import sys
+import time
import traceback
+from threading import Thread
import unittest
from itertools import cycle
from multiprocessing import cpu_count
@@ -40,9 +42,29 @@ _all__ = [
'partition_tests',
]
+# This file has been modified from the original concurrencytest-0.1.2 to wait for the child processes
+# preventing defunct processes and to prefix output with the running PID for debuggability.
CPU_COUNT = cpu_count()
+def wait_for_children(pids):
+ while pids:
+ try:
+ # As Windows doesn't support -1 for all children, loop through each child pid explicitly.
+ for child_pid in pids:
+ pid, exit_status = os.waitpid(child_pid, os.WNOHANG)
+ exit_code = os.waitstatus_to_exitcode(exit_status)
+ if exit_code != 0:
+ pids.remove(pid)
+ if exit_code > 0:
+ print("[pid:{}]: Unexpected exit ({}) for child process ({})".format(os.getpid(), exit_code, pid))
+ else:
+ print("[pid:{}]: Unexpected exit by signal ({}) for child process ({})".format(os.getpid(), abs(exit_code), pid))
+ except ChildProcessError:
+ # No children processes.
+ break
+ # Sleep as the waipid is non blocking.
+ time.sleep(5)
def fork_for_tests(concurrency_num=CPU_COUNT):
"""Implementation of `make_tests` used to construct `ConcurrentTestSuite`.
@@ -61,6 +83,7 @@ def fork_for_tests(concurrency_num=CPU_COUNT):
test_blocks = partition_tests(suite, concurrency_num)
# Clear the tests from the original suite so it doesn't keep them alive
suite._tests[:] = []
+ pids = []
for process_tests in test_blocks:
process_suite = unittest.TestSuite(process_tests)
# Also clear each split list so new suite has only reference
@@ -79,6 +102,8 @@ def fork_for_tests(concurrency_num=CPU_COUNT):
subunit_result = AutoTimingTestResultDecorator(
TestProtocolClient(stream)
)
+ # Set the pid tag for the parent to log with this information.
+ subunit_result.tags(["pid:" + str(os.getpid())], [])
process_suite.run(subunit_result)
except:
# Try and report traceback on stream, but exit with error
@@ -87,7 +112,7 @@ def fork_for_tests(concurrency_num=CPU_COUNT):
# written in one go to avoid interleaving lines from
# multiple failing children.
try:
- stream.write(traceback.format_exc())
+ print("[pid:{}]: {}".format(os.getpid(), traceback.format_exc()))
finally:
os._exit(1)
os._exit(0)
@@ -96,6 +121,10 @@ def fork_for_tests(concurrency_num=CPU_COUNT):
stream = os.fdopen(c2pread, 'rb', 1)
test = ProtocolTestCase(stream)
result.append(test)
+ pids.append(pid)
+ # Monitor our children to prevent leaving <defunct> processes around.
+ wait_thread = Thread(target = wait_for_children, args = (pids, ))
+ wait_thread.start()
return result
return do_fork
@@ -113,7 +142,6 @@ def partition_tests(suite, count):
partition.append(test)
return partitions
-
if __name__ == '__main__':
import time
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.cfg b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.cfg
index 861a9f55426..861a9f55426 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.cfg
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.cfg
diff --git a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.py b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.py
index 447dc4110fe..447dc4110fe 100644
--- a/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2/setup.py
+++ b/src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2-locally-modified/setup.py
diff --git a/src/third_party/wiredtiger/test/suite/wttest.py b/src/third_party/wiredtiger/test/suite/wttest.py
index edd22e346c7..7d94cda9bc8 100755
--- a/src/third_party/wiredtiger/test/suite/wttest.py
+++ b/src/third_party/wiredtiger/test/suite/wttest.py
@@ -42,7 +42,7 @@ except ImportError:
import unittest
from contextlib import contextmanager
-import errno, glob, os, re, shutil, sys, time, traceback
+import errno, glob, os, re, shutil, sys, threading, time, traceback, types
import wiredtiger, wtscenario, wthooks
def shortenWithEllipsis(s, maxlen):
@@ -180,6 +180,38 @@ class ExtensionList(list):
ext = '' if extarg == None else '=' + extarg
self.append(dirname + '/' + name + ext)
+# Custom result class that will prefix the pid in text output (including if it's a child).
+# Only enabled when we are in verbose mode so we don't check that here.
+class PidAwareTextTestResult(unittest.TextTestResult):
+ _thread_prefix = threading.local()
+
+ def __init__(self, stream, descriptions, verbosity):
+ super(PidAwareTextTestResult, self).__init__(stream, descriptions, verbosity)
+ self._thread_prefix.value = "[pid:{}]: ".format(os.getpid())
+
+ def tags(self, new_tags, gone_tags):
+ # We attach the PID to the thread so we only need the new_tags.
+ for tag in new_tags:
+ if tag.startswith("pid:"):
+ pid = tag[len("pid:"):]
+ self._thread_prefix.value = "[pid:{}/{}]: ".format(os.getpid(), pid)
+
+ def startTest(self, test):
+ self.stream.write(self._thread_prefix.value)
+ super(PidAwareTextTestResult, self).startTest(test)
+
+ def getDescription(self, test):
+ return str(test.shortDescription())
+
+ def printErrorList(self, flavour, errors):
+ for test, err in errors:
+ self.stream.writeln(self.separator1)
+ self.stream.writeln("%s%s: %s" % (self._thread_prefix.value,
+ flavour, self.getDescription(test)))
+ self.stream.writeln(self.separator2)
+ self.stream.writeln("%s%s" % (self._thread_prefix.value, err))
+ self.stream.flush()
+
class WiredTigerTestCase(unittest.TestCase):
_globalSetup = False
_printOnceSeen = {}
@@ -586,9 +618,9 @@ class WiredTigerTestCase(unittest.TestCase):
elapsed = time.time() - self.starttime
if elapsed > 0.001 and WiredTigerTestCase._verbose >= 2:
- print("%s: %.2f seconds" % (str(self), elapsed))
+ print("[pid:{}]: {}: {:.2f} seconds".format(os.getpid(), str(self), elapsed))
if (not passed) and (not self.skipped):
- print("ERROR in " + str(self))
+ print("[pid:{}]: ERROR in {}".format(os.getpid(), str(self)))
self.pr('FAIL')
self.pr('preserving directory ' + self.testdir)
if WiredTigerTestCase._verbose > 2:
@@ -834,7 +866,7 @@ class WiredTigerTestCase(unittest.TestCase):
@staticmethod
def prout(s):
- os.write(WiredTigerTestCase._dupout, str.encode(s + '\n'))
+ os.write(WiredTigerTestCase._dupout, str.encode("[pid:{}]: {}\n".format(os.getpid(), s)))
def pr(self, s):
"""
@@ -873,7 +905,7 @@ class WiredTigerTestCase(unittest.TestCase):
def tty(message):
if WiredTigerTestCase._ttyDescriptor == None:
WiredTigerTestCase._ttyDescriptor = open('/dev/tty', 'w')
- WiredTigerTestCase._ttyDescriptor.write(message + '\n')
+ WiredTigerTestCase._ttyDescriptor.write("[pid:{}]: {}\n".format(os.getpid(), message))
def ttyVerbose(self, level, message):
WiredTigerTestCase.ttyVerbose(level, message)
@@ -935,6 +967,16 @@ def islongtest():
def getseed():
return WiredTigerTestCase._seeds
+# We have to override the ThreadsafeForwardingResult implementation of tags so it gets set immediately
+# which allows us to set the pid of the process on our output stream to make debugging easier.
+def immediate_tags(self, new_tags, gone_tags):
+ self.result.tags(new_tags, gone_tags)
+
+def wrap_result_for_tags(thread_safe_result, thread_number):
+ # We use this technique to override the method instead of extending the class as it allows for less changes.
+ thread_safe_result.tags = types.MethodType(immediate_tags, thread_safe_result)
+ return thread_safe_result
+
def runsuite(suite, parallel):
suite_to_run = suite
if parallel > 1:
@@ -942,16 +984,19 @@ def runsuite(suite, parallel):
if not WiredTigerTestCase._globalSetup:
WiredTigerTestCase.globalSetup()
WiredTigerTestCase._concurrent = True
- suite_to_run = ConcurrentTestSuite(suite, fork_for_tests(parallel))
+ suite_to_run = ConcurrentTestSuite(suite, fork_for_tests(parallel), wrap_result=wrap_result_for_tags)
try:
if WiredTigerTestCase._randomseed:
WiredTigerTestCase.prout("Starting test suite with seedw={0} and seedz={1}. Rerun this test with -seed {0}.{1} to get the same randomness"
.format(str(WiredTigerTestCase._seeds[0]), str(WiredTigerTestCase._seeds[1])))
+ result_class = None
+ if WiredTigerTestCase._verbose > 1:
+ result_class = PidAwareTextTestResult
return unittest.TextTestRunner(
- verbosity=WiredTigerTestCase._verbose).run(suite_to_run)
+ verbosity=WiredTigerTestCase._verbose, resultclass=result_class).run(suite_to_run)
except BaseException as e:
# This should not happen for regular test errors, unittest should catch everything
- print('ERROR: running test: ', e)
+ print("[pid:{}]: ERROR: running test: {}".format(os.getpid(), e))
raise e
def run(name='__main__'):