Skip to content

Commit 839faf7

Browse files
authored
ci: Return custom exit code to indicate known shm leak failure in L0_backend_python bls test (#7485)
1 parent 3443dd6 commit 839faf7

File tree

10 files changed

+81
-45
lines changed

10 files changed

+81
-45
lines changed

qa/L0_backend_python/argument_validation/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
CLIENT_PY=../python_unittest.py
28+
CLIENT_PY=../test_infer_shm_leak.py
2929
CLIENT_LOG="./arg_validation_client.log"
3030
TEST_RESULT_FILE='test_results.txt'
3131
SERVER_ARGS="--model-repository=${MODELDIR}/argument_validation/models --backend-directory=${BACKEND_DIR} --log-verbose=1"

qa/L0_backend_python/bls/test.sh

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
CLIENT_PY=../python_unittest.py
28+
CLIENT_PY=../test_infer_shm_leak.py
2929
CLIENT_LOG="./bls_client.log"
3030
TEST_RESULT_FILE='test_results.txt'
3131
source ../../common/util.sh
3232

3333
TRITON_REPO_ORGANIZATION=${TRITON_REPO_ORGANIZATION:=http://github.com/triton-inference-server}
3434

3535
RET=0
36-
rm -fr *.log ./models *.txt
36+
rm -fr *.log ./models *.txt *.xml
3737

3838
# FIXME: [DLIS-5970] Until Windows supports GPU tensors, only test CPU
3939
if [[ ${TEST_WINDOWS} == 0 ]]; then
@@ -119,30 +119,35 @@ if [[ ${TEST_WINDOWS} == 0 ]]; then
119119

120120
for MODEL_NAME in bls bls_memory bls_memory_async bls_async; do
121121
export MODEL_NAME=${MODEL_NAME}
122-
123-
python3 -m pytest --junitxml="${MODEL_NAME}.${TRIAL}.${CUDA_MEMORY_POOL_SIZE_MB}.report.xml" $CLIENT_PY >> $CLIENT_LOG 2>&1
124-
if [ $? -ne 0 ]; then
122+
# Run with pytest to capture the return code correctly
123+
pytest --junitxml="${MODEL_NAME}.${TRIAL}.${CUDA_MEMORY_POOL_SIZE_MB}.report.xml" $CLIENT_PY >> $CLIENT_LOG 2>&1
124+
EXIT_CODE=$?
125+
if [ $EXIT_CODE -ne 0 ]; then
125126
echo -e "\n***\n*** ${MODEL_NAME} ${BLS_KIND} test FAILED. \n***"
127+
RET=$EXIT_CODE
126128
cat $SERVER_LOG
127129
cat $CLIENT_LOG
128-
RET=1
129130
fi
130131
done
131132

132-
set -e
133-
134133
kill_server
135134

136-
# Check for bls 'test_timeout' to ensure timeout value is being correctly passed
137-
if [ `grep -c "Request timeout: 11000000000" $SERVER_LOG` == "0" ]; then
138-
echo -e "\n***\n*** BLS timeout value not correctly passed to model: line ${LINENO}\n***"
139-
cat $SERVER_LOG
140-
RET=1
135+
set -e
136+
137+
# Only check the timeout value if there is no error since the test
138+
# may fail before the test_timeout case gets run.
139+
if [ $RET -eq 0 ]; then
140+
# Check for bls 'test_timeout' to ensure timeout value is being correctly passed
141+
if [ `grep -c "Request timeout: 11000000000" $SERVER_LOG` == "0" ]; then
142+
echo -e "\n***\n*** BLS timeout value not correctly passed to model: line ${LINENO}\n***"
143+
cat $SERVER_LOG
144+
RET=1
145+
fi
141146
fi
142147

143-
if [[ $CUDA_MEMORY_POOL_SIZE_MB -eq 128 ]]; then
148+
if [[ $CUDA_MEMORY_POOL_SIZE_MB -eq 256 ]]; then
144149
if [ `grep -c "Failed to allocate memory from CUDA memory pool" $SERVER_LOG` != "0" ]; then
145-
echo -e "\n***\n*** Expected to use CUDA memory pool for all tests when CUDA_MEMOY_POOL_SIZE_MB is 128 MB for 'bls' $BLS_KIND test\n***"
150+
echo -e "\n***\n*** Expected to use CUDA memory pool for all tests when CUDA_MEMORY_POOL_SIZE_MB is 256 MB for 'bls' $BLS_KIND test\n***"
146151
cat $SERVER_LOG
147152
RET=1
148153
fi
@@ -342,10 +347,10 @@ set -e
342347

343348
kill_server
344349

345-
if [ $RET -eq 1 ]; then
346-
echo -e "\n***\n*** BLS test FAILED. \n***"
347-
else
350+
if [ $RET -eq 0 ]; then
348351
echo -e "\n***\n*** BLS test PASSED. \n***"
352+
else
353+
echo -e "\n***\n*** BLS test FAILED. \n***"
349354
fi
350355

351356
exit $RET

qa/L0_backend_python/custom_metrics/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
CLIENT_PY=../python_unittest.py
28+
CLIENT_PY=../test_infer_shm_leak.py
2929
CLIENT_LOG="./custom_metrics_client.log"
3030
TEST_RESULT_FILE='test_results.txt'
3131
source ../../common/util.sh

qa/L0_backend_python/request_rescheduling/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
CLIENT_PY="../python_unittest.py"
28+
CLIENT_PY="../test_infer_shm_leak.py"
2929
CLIENT_LOG="./request_rescheduling_client.log"
3030
TEST_RESULT_FILE='test_results.txt'
3131
source ../../common/util.sh

qa/L0_backend_python/setup_python_enviroment.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ apt-get update && apt-get -y install \
151151
libboost-dev
152152
rm -f /usr/bin/python3 && \
153153
ln -s "/usr/bin/python3.${PYTHON_ENV_VERSION}" /usr/bin/python3
154-
pip3 install --upgrade install requests numpy virtualenv protobuf
154+
pip3 install --upgrade requests numpy virtualenv protobuf
155155
find /opt/tritonserver/qa/pkgs/ -maxdepth 1 -type f -name \
156156
"tritonclient-*linux*.whl" | xargs printf -- '%s[all]' | \
157157
xargs pip3 install --upgrade

qa/L0_backend_python/test.sh

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,20 @@ if [ "$TEST_JETSON" == "0" ]; then
425425
# between dependencies.
426426
setup_virtualenv
427427

428+
set +e
428429
(cd ${TEST} && bash -ex test.sh)
429-
if [ $? -ne 0 ]; then
430+
EXIT_CODE=$?
431+
if [ $EXIT_CODE -ne 0 ]; then
430432
echo "Subtest ${TEST} FAILED"
431-
RET=1
433+
RET=$EXIT_CODE
434+
435+
# In bls test, it is allowed to fail with a strict memory leak of 480 bytes with exit code '123'.
436+
# Propagate the exit code to make sure it's not overwritten by other tests.
437+
if [[ ${TEST} == "bls" ]] && [[ $EXIT_CODE -ne 1 ]] ; then
438+
BLS_RET=$RET
439+
fi
432440
fi
441+
set -e
433442

434443
deactivate_virtualenv
435444
done
@@ -438,11 +447,13 @@ if [ "$TEST_JETSON" == "0" ]; then
438447
if [[ ${PYTHON_ENV_VERSION} = "10" ]] && [[ ${TEST_WINDOWS} == 0 ]]; then
439448
# In 'env' test we use miniconda for dependency management. No need to run
440449
# the test in a virtual environment.
450+
set +e
441451
(cd env && bash -ex test.sh)
442452
if [ $? -ne 0 ]; then
443453
echo "Subtest env FAILED"
444454
RET=1
445455
fi
456+
set -e
446457
fi
447458
fi
448459

@@ -459,12 +470,14 @@ for TEST in ${SUBTESTS}; do
459470
# between dependencies.
460471
setup_virtualenv
461472

473+
set +e
462474
(cd ${TEST} && bash -ex test.sh)
463475

464476
if [ $? -ne 0 ]; then
465477
echo "Subtest ${TEST} FAILED"
466478
RET=1
467479
fi
480+
set -e
468481

469482
deactivate_virtualenv
470483
done
@@ -475,4 +488,14 @@ else
475488
echo -e "\n***\n*** Test FAILED\n***"
476489
fi
477490

478-
exit $RET
491+
# Exit with RET if it is 1, meaning that the test failed.
492+
# Otherwise, exit with BLS_RET if it is set, meaning that the known memory leak is captured.
493+
if [ $RET -eq 1 ]; then
494+
exit $RET
495+
else
496+
if [ -z "$BLS_RET" ]; then
497+
exit $RET
498+
else
499+
exit $BLS_RET
500+
fi
501+
fi

qa/L0_backend_python/python_unittest.py renamed to qa/L0_backend_python/test_infer_shm_leak.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import os
3434
import unittest
3535

36+
import pytest
3637
import shm_util
3738
import tritonclient.grpc as grpcclient
3839
from tritonclient.utils import *
@@ -41,11 +42,13 @@
4142
# we overwrite the IP address with the TRITONSERVER_IPADDR envvar
4243
_tritonserver_ipaddr = os.environ.get("TRITONSERVER_IPADDR", "localhost")
4344

45+
# The exit code 123 is used to indicate that the shm leak probe detected a 480
46+
# bytes leak in the bls sub-test. Any leak other than 480 bytes will cause the
47+
# test to fail with the default exit code 1.
48+
ALLOWED_FAILURE_EXIT_CODE = 123
4449

45-
class PythonUnittest(unittest.TestCase):
46-
def setUp(self):
47-
self._shm_leak_detector = shm_util.ShmLeakDetector()
4850

51+
class TestInferShmLeak:
4952
def _run_unittest(self, model_name):
5053
with grpcclient.InferenceServerClient(f"{_tritonserver_ipaddr}:8001") as client:
5154
# No input is required
@@ -54,15 +57,17 @@ def _run_unittest(self, model_name):
5457

5558
# The model returns 1 if the tests were successfully passed.
5659
# Otherwise, it will return 0.
57-
self.assertEqual(
58-
output0, [1], f"python_unittest failed for model {model_name}"
59-
)
60-
61-
def test_python_unittest(self):
62-
model_name = os.environ["MODEL_NAME"]
63-
with self._shm_leak_detector.Probe() as shm_probe:
64-
self._run_unittest(model_name)
60+
assert output0 == [1], f"python_unittest failed for model {model_name}"
6561

62+
def test_shm_leak(self):
63+
self._shm_leak_detector = shm_util.ShmLeakDetector()
64+
model_name = os.environ.get("MODEL_NAME", "default_model")
6665

67-
if __name__ == "__main__":
68-
unittest.main()
66+
try:
67+
with self._shm_leak_detector.Probe() as shm_probe:
68+
self._run_unittest(model_name)
69+
except AssertionError as e:
70+
if "Known shared memory leak of 480 bytes detected" in str(e):
71+
pytest.exit(str(e), returncode=ALLOWED_FAILURE_EXIT_CODE)
72+
else:
73+
raise e

qa/L0_dlpack_multi_gpu/test.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
SERVER=/opt/tritonserver/bin/tritonserver
2929
SERVER_ARGS="--model-repository=`pwd`/models --log-verbose=1"
30-
CLIENT_PY=./python_unittest.py
30+
CLIENT_PY=./test_infer_shm_leak.py
3131
CLIENT_LOG="./client.log"
3232
EXPECTED_NUM_TESTS="1"
3333
TEST_RESULT_FILE='test_results.txt'
@@ -52,8 +52,8 @@ rm -fr *.log ./models
5252
mkdir -p models/dlpack_test/1/
5353
cp ../python_models/dlpack_test/model.py models/dlpack_test/1/
5454
cp ../python_models/dlpack_test/config.pbtxt models/dlpack_test
55-
cp ../L0_backend_python/python_unittest.py .
56-
sed -i 's#sys.path.append("../../common")#sys.path.append("../common")#g' python_unittest.py
55+
cp ../L0_backend_python/test_infer_shm_leak.py .
56+
sed -i 's#sys.path.append("../../common")#sys.path.append("../common")#g' test_infer_shm_leak.py
5757

5858
run_server
5959
if [ "$SERVER_PID" == "0" ]; then

qa/L0_warmup/test.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export CUDA_VISIBLE_DEVICES=0
4242

4343
CLIENT=../clients/image_client
4444
CLIENT_LOG="./client.log"
45-
CLIENT_PY=./python_unittest.py
45+
CLIENT_PY=./test_infer_shm_leak.py
4646
EXPECTED_NUM_TESTS="1"
4747
TEST_RESULT_FILE='test_results.txt'
4848

@@ -449,8 +449,8 @@ mkdir -p models/bls_onnx_warmup/1/
449449
cp ../python_models/bls_onnx_warmup/model.py models/bls_onnx_warmup/1/
450450
cp ../python_models/bls_onnx_warmup/config.pbtxt models/bls_onnx_warmup/.
451451

452-
cp ../L0_backend_python/python_unittest.py .
453-
sed -i 's#sys.path.append("../../common")#sys.path.append("../common")#g' python_unittest.py
452+
cp ../L0_backend_python/test_infer_shm_leak.py .
453+
sed -i 's#sys.path.append("../../common")#sys.path.append("../common")#g' test_infer_shm_leak.py
454454

455455
run_server
456456
if [ "$SERVER_PID" == "0" ]; then

qa/common/shm_util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
# Copyright 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# Copyright 2018-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44
#
55
# Redistribution and use in source and binary forms, with or without
66
# modification, are permitted provided that the following conditions
@@ -441,6 +441,9 @@ def __exit__(self, type, value, traceback):
441441
print(
442442
f"Shared memory leak detected [{shm_region}]: {curr_shm_free_size} (curr free) < {prev_shm_free_size} (prev free)."
443443
)
444+
# FIXME DLIS-7122: Known shared memory leak of 480 bytes in BLS test.
445+
if curr_shm_free_size == 1006576 and prev_shm_free_size == 1007056:
446+
assert False, f"Known shared memory leak of 480 bytes detected."
444447
assert not shm_leak_detected, f"Shared memory leak detected."
445448

446449
def _get_shm_free_sizes(self, delay_sec=0):

0 commit comments

Comments
 (0)