Skip to content

Commit

Permalink
Add multithreading test
Browse files Browse the repository at this point in the history
  • Loading branch information
JanCBrammer committed Oct 17, 2024
1 parent 478aa8d commit 746a927
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
run: pytest INCHI-1-TEST/tests/test_executable

- uses: ./.github/actions/compile_inchi_lib
- name: Run multithreading test
run: python INCHI-1-TEST/tests/test_library/test_multithreading.py
- uses: ./.github/actions/regression_tests
with:
artifact-name: regression-test-results_glibc_gcc
Expand Down Expand Up @@ -70,6 +72,8 @@ jobs:
run: pytest INCHI-1-TEST/tests/test_executable

- uses: ./.github/actions/compile_inchi_lib
- name: Run multithreading test
run: python INCHI-1-TEST/tests/test_library/test_multithreading.py
- uses: ./.github/actions/regression_tests
with:
artifact-name: regression-test-results_musl_gcc
Expand Down
8 changes: 8 additions & 0 deletions INCHI-1-TEST/tests/test_library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ python -m INCHI-1-TEST.tests.test_library.data.pubchem.validate <subset>

Note that validation isn't available for `compound3d` (PubChem doesn't provide file hashes).

## Multithreading tests

Test the thread safety of the InChI library by running

`python INCHI-1-TEST/tests/test_library/test_multithreading.py`

The script triggers a segfault should the thread safety of the library be compromised.

## Invariance tests

Invariance tests are meant to detect problems with InChI's canonicalization algorithm.
Expand Down
48 changes: 48 additions & 0 deletions INCHI-1-TEST/tests/test_library/test_multithreading.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
This script is meant to trigger segfaults.
Unix systems return exit code 139 when a process terminates due to a segfault.
139 = 128 + 11,
where 128+n means "Fatal error signal 'n'", see https://tldp.org/LDP/abs/html/exitcodes.html,
and 11 means "SIGSEGV", i.e., segfault, see wikipedia.org/wiki/Signal_(IPC)#POSIX_signals.
"""

import threading
import ctypes
from pathlib import Path
from inchi_tests.inchi_api import make_inchi_from_molfile_text
from sdf_pipeline.utils import read_records_from_gzipped_sdf


SDF_PATH = Path("INCHI-1-TEST/tests/test_library/data/ci/inchi.sdf.gz")
INCHI_LIB_PATH = Path("INCHI-1-TEST/libs/libinchi.so.main")
# INCHI_LIB_PATH = Path("INCHI-1-TEST/libs/libinchi.so.v1.06")
INCHI_LIB = ctypes.CDLL(str(INCHI_LIB_PATH))


class ConsumerThread(threading.Thread):
def __init__(self, inchi_lib, molfile):
super().__init__()
self.inchi_lib = inchi_lib
self.molfile = molfile

def run(self):
(_, inchi, _, _, _) = make_inchi_from_molfile_text(
self.inchi_lib,
self.molfile,
"",
)
print(inchi)


if __name__ == "__main__":

threads = [
ConsumerThread(INCHI_LIB, molfile)
for molfile in read_records_from_gzipped_sdf(SDF_PATH)
]

for thread in threads:
thread.start()

for thread in threads:
thread.join(timeout=5)

0 comments on commit 746a927

Please sign in to comment.